Golang Tutorial: Build A Beautiful CLI Todo App With Support for Piping

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone welcome to the screencast where we build a beautiful to do command line application in go so if you are new to go and you're looking for something to practice this is a good one and i think you will love it so before we start writing code i would like to show you what we'll be building in this course so i've compiled the app and the app is on my desktop so this is the app you see that it's currently saying valid operation so we need to pass it some command so let's say add recording screencast that's recording just a picture take your work and and what else just to do so i have three to do is added to it now we can issue the list command to show all our to-do's so right now what you are seeing is because i've added some to those previously but as you can see you see the ones that we just added one two three four five six seven looks beautiful and we finished two this is what we are building and we can of course maximum of the to do that's completed by saying complete so let's make the test to do mine complete i'll go ahead and do list let me clear my screen and do it again and as you can see it looks really beautiful so we can of course delete it to do by saying delete equals um let's delete the second one reply image and then i will list again and you see that the reply email is gone we're currently using the json file to uh to store the data so as you can see the data is stored using jc so i will show you in the screencast how to read and convert this to good data structure and how we can use it to build out this beautiful interface on the command line so stick with me in this few minutes of screencast and you will learn how to build exactly what you are seeing on your screen fantastic so there's currently nothing on the directory so we're going to start bringing in our folders first say let me use the make da to make it faster it's faster than typing all the directories so we're going to have cmd slash to do so this is our main package where we're going to have our executable we're also going to have uh we're um to have a touch make file i think we can keep it simple at this start so expand the folder let's also do go mode it i'll put it in my github namespace i just named it to do app and it's asking us to run go mods tidy so which i will run all right i think everything looks good from here so i'm using go 1.18 next step is to add some code so this is the main package so i will say main so this is our main package and of course let's print let's put the hello world all right so this is hello world so we need to run this to run it i'd like to type make run to do and then it should run so let's go and atta target to run to do and then we do go run cmd slash to do the make comment should not work we should say hello world fantastic next step is to work on the data structures which is our to-do items so i will come here and create a new file we can create so if we like we can actually create another folder but i'll just create it directly under this one to do which is the main data structure so we have a to do package type let's have an item type of struct the task itself if it is done or not this is boolean the time it was created and the time it was completed i think this is good also we need at least a collection of items so this is the mental delay so we can say type we can name it to dose and soft type slice of item right next step we we need to add methods to this like how to add to do how to delete it to do how to market to do as completed so i will go ahead and say um function pointer to t and um to reduce add the tax we are adding we're not returning anything so to do would be item the task like we put up there the task will be false actually it's false by default so you can leave that out back here creator that is time.now and completed that i'll leave it at the default time which is this empty struct so now that we have this we need to append it to the list to do that we need to dereference the list because we are using pointer here and the reference and then add the studio so that is the add method the second method we are going to work on is how to market to do as completed so funk same signature so we just copied this quickly to make things faster and then we need the index which i will say index and add some space here so let's get to reference to the main data structure which is this one if our index the passing is less than equal to zero just little check here or it is greater than the length of the copy we want to return error here so that means we can arrows errors.name or whatever invalid index right if the index is valid we just do ls the index index minus one completed at time dot number and don't need to set down to true so we just copy this quickly and of course since that is the case we just return me if everything works all right the next method we are going to work on is a delete method let me make some room for myself so funk bring this sorry i want to bring this here again don't mind my laziness pretend we're going to do like similar thing here and we're going to now do the referencing again this time around we do this one basically we are slicing from beginning to index minus one and then we spread the rest across index i mean i miss the quote the column all right so this is going to this is going to set the list to everything minus the index the one that has this index so at this point we can return nail as well what else we need to do the so we can add it to do we can market to do as completed we can delete it to do so what does we need how about loading the to do from file however writing it to the file all right so let's first of all load it from the file system so function similar signature again and i will call it load the name of the file file name potential error so file error iout i o u2 dot read file so gold is duplicating iout so we have to be careful with the voice to work so if that is the case we return error at this point we have the file this error can be two different things can happen here one is if it's a file not file no problem that means if not um error is that means we've not created a file now application is just starting around and always dots uh error not exists if that is the case no problem i will just return near here and if not we return an error at this point we just check the length of the file too if it's zero we'll return there because that means nothing is in the firearm it's not really an error that means we don't have any to do in there and then the next step is to convert the data from here into the struct object so basically we are about to unmash our data into the list that one is quite easy since we have we have error defined here already we just do json that our machine the data into the data structure itself of course we check for error again if error is not only we return the error at this point we can return here so this is the loading code basically just load the file with the file or masha and exit no problem no the next method we are going to work on is how to write so when we load when we added to do we also need to write it back into the file so we need the we need another method called storm and i will take file name again anytime you're doing anything with files you're probably going to have an error so always return error i would say data basically we're going to measure this so i just do json.martian and i pass in this of course we check for an error again if we have an error we return that error else we have the data here to write back to the file we can just return io ut dot write file the file name and the data that we want to write and then the mode this is 064 for this is the permission right so this is good i think we have all the code now for what to do next thing is to go and write the main method so we can start using it from here to the const let's say to do file will be we can just name it to do the adjacent if we want to keep it hidden we can put a dot before it let's make some flag remember from the demo we had a an ad so flag just to see if it is true if add is true then we're just going to add it first by default add in here right and then i'm going to say flat.pass i want to take it one thing at a time we'll come and add more here but i want us to take it at one united time so i would say to do um it was a pointer to do dot to do right so this is the list remember the list that is created here so this list this our to do is now have all the meter that we created earlier so we can use it now all right so time to say if we have let's try to load the to do when we start the application um to do start get or load sorry and then to do file if we do have an error this is the time to exit so i would uh i will print something to the up to the standard attribute f printer ln i will say os dot std standard error actually so i'll print something out there which is error message i got i print it to standard error and then i usually takes it i just exited one all right after that we can do our switch so if we have uh let's say case add um what we need what do we want to do we just want to add um to do's dot add what is the tax let's say sample example to do right let's keep it this simple for now default and then default i will do something similar here but this time around i'll do a cd out i still have not so let's test the code we've written so far we can do go run add to test it but nothing is going to happen because don't forget let me show you what don't forget now we've added if you go to the add method so we've appended the data structure to this our list but we are not saving it yet so we need to save it so we need to go in here after we do that we should save it by saying error is equal to produce store we are storing the term to do file and if there is an error we we just do the same thing here or something like that all right so let's run the code again and now you see that we have a to do digestion without to do created fantastic so the next step is to add more flags so we can do it to do how about complete so to market to do as complete we can do an end complete the index will be zero mark it to do as completed so with that i can come here case um case a complete um greater than zero that is when we want it and we can actually greater than zero and less than equal to the last high m is like greater than zero and add the rest of it but it's okay we need to dereference so how to make it as completed is basically doing the same thing to do's i think that returns an error so we can do error to do that complete passing with the conflict which is which holds the index right very important that you hold this index and if you notice we have we have to continue doing this saving um we have to do a very similar thing here and there and for me this is becoming repetitive so what i want to do quickly is to do some um is to do this uh so we'll come back and refactor let's just continue building we'll come back and refactor so let's do now complete one so we go into our to do let's look for done tax done is false completed at the default timestamp so something is not working let's look at it one more time um to do not complete within oh oh we're not saving it we're not saving it yet so we need to save we need to store it back and this is why i was saying that this code is becoming there's a lot of duplication and because of error handling we need to remove this so let's run it again and then go back to the to do you see now that it worked so let's just do a quick recap for in case you are getting confused we have two flags add and complete we just pause the flag this is standard and go way of doing things then we initialize our to-do here this is the to-do structure that we have here right then when the application runs we try to load the to do if we can if we find a file and load it great then we just populate this data structure but if there is nothing inside no problems then we are switching we have two cases now one is when a user wants to add it to do we as acute dispersion of the code when the user want to max it to do us completed we look at this version of the code and for this ad we are just calling the add and then we are calling store we're calling complete we're calling store so most of the methods will follow similar pattern so the second one third one is the delete delete is simple as well but we have to do the same thing i'll just name it there and then delete is very similar to this because it is an index delete it to do all right so to delete it to do i'm just going to copy this whole block and mark it as delete so we are using the delete now when we try we try to delete if we run into an error of course we exit errors we try to store it back so that we can persist the changes we've made and that is it so let's run it again and right now we have just want to do so let me add one more and then all right so we go back now we have to to do so how about we delete the first one and delete one so it's gone right we can go again and delete everything is gone so it's working all the metals are working we can react add them back shut more to do and let's add a little bit more so that we can implement our list so we have three here time for us to add another flag called lists and this list is it can be anything we just make it a billion so when the list is set to true we should at least so we take the list and go back similar to anyhow let's come here case oops i want to put in again all right so what we want to do list is basically i will just say to do the trend that's the reason why i'm doing it because i think we're going to write more code in order for this to work so what i'm going to go and create that method right now what we can let's say for for i i can range over to just the underline data structure of t and we just do print print f is what i need this is the index this is the to do itself and then we put new line it will be the index i attend the task because i want the index to start from one or just increment it so here now we just released and then we see our grid to do's so sample to do sample to do something to do that what we have exactly because it's a test file you can edit it like you know take a walk and then when you run it take a walk right that means you can modify the file so like what you want to be careful so that you don't make a syntax error here if we make a syntax and we'll see let's make a synthetic we should see an error from the invalid d after barrier so code works all right so we have the print method the print method needs more code and we'll come to that shortly but also how about this idea of say we want to write echo add new to do via pipe however when we want to do this of course we now run out to do and then pass this so we need let's implement this then we'll go back and implement the print the first thing i want to do is to work on the new method so i'll call it let me just put the function here get input get input we're going to read from the i o reader and then all the x and we return arrow sorry with unlike a string or an error all right all right okay so if we have some arguments so if you so basically if you type if you if they do this we take that instead of the pipe so if len x is greater than zero we just join everything and return it stream that join uh we can act by empty space and then we return it that's good this is the case that we have right now what we what you're going to have right now so we're going to replace this with it then ness is [Music] the buffer so we're going to say scanner both are you new scanner scan we are going to this is just to give us the opportunity to read from the uh in a standard input of the other program there's nothing too complicated here it's scanner that error and error is not me if we don't have an error we want to return this if not we learn we check the length of the test comma text uh if he's empty we should return your error this arrow's not going to be near this point certainly i don't know all right at this point we just return the text another way is to say text read this once and then we do this that way we are now executing this text twice for me this is better so we need to take this getting treatment now use it in our ad section all right so we're going to sort of rewrite this so the task an error is um get input input from where like we said standard input std device where we want to read from so flag.x we need to spread this and to spread it fantastic so but if we do have an arrow don't forget to do this so i'll just do this one and i will have the text this is the string there we do to do's dot add task and of course it needs to be stored so we go and store it so that's great so time to test wait for me to test it out i'll do go build um cmd so i'll build a binary here so to do ah let's add the first one after the code modification let's look at the to-do file so we can see after the code modification and can do to do lists to also succeed let me expand this great how about now echo sending data from another program pipe i want to do one minute to pass their flag fantastic it came let me clay and then released sending data from another program so as you can see everything works so we're almost done let's go back let's take a look at the code one more time i think what is spending now is that print section for us to make it look pretty and then we can add some refactoring and all that all right to make it look pretty we're going to need a third party library this is the first time that we're going to add a third party library and so let me open my browser quickly and i show you the library that we're going to add um this is sim smart simple library that uh i think just walk so this is it on github and i'll leave a link to it on the description so you can see you see this is the table and do as you can see it doesn't have color say it but if you look if you go into the examples for instance you will see colorize and this is where i found the code for the colors and this is the constant so we're going to bring some of this code over to our own code so let me move this out and then we can continue building so the first thing is to do go get all right go get it and i think we have it now let's look at the go mod fantastic looks great so let's go to our print we should delete this one now let's create a table simple table simple table dot new all right so we need the header of the table so table table header will be equal to a simple table header all right so we need to add some cells to the header which is it is it's a pointer to simple table cells right and this is where we add uh different uh cells so we first of all let me put us an alignment to simple table alignment center if you like you can make it a simple table dot align center if you like you can make it uh right or left or any how you want it and then this is the id so we can keep it this way i would like to duplicate this so we are going to have four by four id the task itself we are going to have if it is done or not we're going to have for created that i'm going to have for completed that can i change this a line right for this for these two all right so the next thing i want to do is the cells which is the data itself so let's do our cells let's point out to simple table cells the same thing that we have here all right so let's look to our data i'll name it idx or index and the i10 range you've seen this before with the reference because you need to answer the underlying data and that will be referenced we are going to increment this because we want the index to start from one and um for now i'm just going to do cells that append i'll come and adjust this a little bit later we are appending the pointer to a slice of simple table cells all right so it's very similar to what we have here actually but uh i won't add alignment so the test is um i've just put a idx for this remember the first one is the number since it's an integer and it requires a string we can do sprint f f strings f and pass it d to get the string version text is uh taxed this time around so we can do item dot task and um text is so dom we need something similar to do for formatting it so item dot done so this will be true or false basically the rest i will do text um item dot created and i'll just do to string for now it won't look that good but it's no problem all right i can dot completed to string right you can do format i tried the lens you format and make it short format time dot uh let's look for one format here everything might make sense look for something that is short nothing is really short here maybe maybe this one yeah just take that all right so after the loop we need the table body to be equal to simple table body and then set the cells to ourselves this is what we just created right you remember we just created this and then this is basically appending our history then we are setting it as a table cells all right uh this is we are almost done just to add the footer table footer we can do simple table footer cells everything is about cells uh point out to simple table service and then align uh simple table align so instead of me typing it all over again i just copy this let's save some time we wanted to spam all the resources pane 5 and then text for now i'll just your traders are here or come back to adjust some of these things shortly but let's set style i can be simple table style uh like the unicode style that i've i've tried and look i mean that many styles that you can try as well and then the last thing is just to print it so look at the code quickly then we can go and run it created an instance of the table created the header created the cells and make it the body and then the footer and then print it right so next to this wrong go build cmd to do since we have the to-do files here we'll just be able to run it as to do list wow i don't know about you but this feels great everything is coming out really really nice right so the only pending thing is the column so let's go work on the column i'm going to put a file here colors so the colors you remember i'm bringing this is not like code i'm writing but i'm basically taking it from the sample so let me bring it back so i'm bringing this from here and this is the constant and these are the color function this is all we're taking from there right so we don't need to waste time doing it all over again there's nothing much to learn here all right so go back to our to do into the print function and let's start adding some of the adding colors to them so the first place i want to add color colors in here so i will say task is by default the text will be blue so item.task but if item dot dom then watching talks to f prince printf and i'm doing this because i want to add something i want to add a check mark so we change it to green bring out the string here so this will be unicode [Music] 2705 for that checkbox and then our to-do will be here i10 dot and then we can replace this one with task that is one let's run it and see it's not working because we need to butte beard i run it exactly so everything is blue but no no to do matters complete so let's say complete let's make the first one has completed so we can go back now what a code working pretty well okay uh another thing i want to touch is um the this section of the code where you have your tradition so first of all let's say let's add a new method here called count pending from i'll take the signature to save you some time contending compensation return on end basically um for we don't need the index i turn across the range with the reference the t if i turn is not done we just increment two time and we return to it at this point this is what i'm needing the prints here to say red let's print you have pending to reduce 30. count pending all right so let's do that run it again fantastic so we have it i think that's about it um you can [Music] like we can have like yes or no here so let me quickly do that thank it to look better uh if we have like a yes or no the instead so i would say uh don just know by default on the note will be blue no and if it is done will be green dawn will be green yes so down here we can replace all this with them and to build it where the command to be dude around the list so we it looks really good all right so this is the app thank you so much for watching my name is joseph abba please support me by subscribing to my channel i'm creating more videos and i hope you enjoyed this tutorial there's a lot of improvement that can be made especially with testing with the video is getting too long so i'm going to stop now maybe i can do like a follow-up video and add tests to the code also we need some refactoring here because of how many times we've repeated some of the code here in maine especially something like this another way to avoid this is to is to bring the saving into the like complete for instance but that is the function doing more than one thing so it breaks the single responsibility principle so i won't do that but trust me there's opportunity to refactor this code to make it cleaner to make it sharper and all that but this is it so thank you once again and see you next time bye
Info
Channel: Abah Joseph
Views: 82,745
Rating: undefined out of 5
Keywords: Build A Beautiful app, Go, advanced golang, cobra cli, command line go application, flutter, flutter tutorial, go cli tutorial, go command line argument, go concurrency, go programming tu, golang command-line, golang for beginners, golang microservices, golang piping tutorial, golang project, golang tutorial, golang tutorial 2022, golang tutorial for beginners, javascript, latest javascript todo app, piping in golang, simple todo app, todo app tutorial
Id: j1CXoOQXbco
Channel Id: undefined
Length: 48min 14sec (2894 seconds)
Published: Thu May 26 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.