Auto-generated transcript Let me just quickly recap what we did last time. So I'm not even sure what we did last time but we we basically built all of the upload functionality over here to upload files and folders to Google Drive. We also built the a couple functions over here to delete the previous folder so we don't have duplicates in our drive and also to create subfolders so we have like a hierarchy of folders and subfolders in our projects right so this is very um like this project is very close to completion already like this is already something you can put in production and actually use in the real world right but there's a couple more features i want to add so first of all i want to add the ability to read get ignore files basically i want to be able to you see this get ignore file over here i want to be able to read the git ignore file of every single project and then based on that decide which files and folders we're going to upload and which ones we're going to ignore all right because we don't want to upload stuff like this the token the client the authorization tokens and sensitive secrets like that on onto google drive right we want to keep these things local to our machine basically anything that you're not going to upload to github or source control You shouldn't upload to drive or any other backup solution either, right? So we're going to do that today in this video. Let's go back to sync go This is where I'm going to build the entire thing. Let me just walk you through what we're going to do There's two parts to this. So first of all, let me open up config dot JSON and Over here. You can see the ignore keyword, right? We want to basically be able to to use this ignore list over here this is the global ignore this is going to take effect in every single project basically in every single project that we synchronize we want to ignore the node modules the vent this is the python environment virtual environment the dot get folder we don't need to upload this either right this stuff will be ignored in every single project that we upload, right? Along with that, so this is one ignore list, right? Along with that, we want to also be able to use the git ignore files in every single project. And this is the second ignore list. So there's going to be two lists of files and folders that we want to ignore in every single upload, right? And we're basically just going to build those two lists and then combine them and then just make sure we're not uploading them that we're skipping them right so let's get started the very first thing i'm going to do is all the way down here at the end of the file create a function called read get ignore this will take a folder which will just be a pointer to the folder object and it will return two things first the list of strings of file names that we need to ignore and second and error over here all right now let's do f and error equals os dot open let's open up the git ignore file the file path for this will be file path dot join will say join the folder path with dot git ignore so we're saying every single git ignore file is going to be inside the folder at the root of the folder right this is how usually git ignore this is how git source control works, right? So yeah, we'll create the path and open up the file. We'll make sure to handle the error as well. Let just say return nil and error And of course make sure to use defer to close the file when you done with it now uh let me just quickly show you the git ignore file again what this basically looks like is we have a bunch of file names and folder names per line right so on every single line you have one folder or one file name right so we want to be able to scan this per line right so let's do that To do that in Go, we can use something called above.io.scanner. I'll say new scanner over here. Pass in the reader. This will just be the file. And we'll call this s. And then we'll say for s.scan. And then we'll say append to ignore. Append. And we will append s.text. So this will scan every single line in the gitignore file and return the text of it, right? Return it as a string. Now, we also want to make sure that we use, that we clean up this string by using strings.trimspace. And this will return the string with all leading and trailing whitespace removed, right? So basically, I don't want to have something like, so we have client.json in gitignore, right? I don't want to be able to like add a bunch of spaces over here and empty characters and scan those as well, right? Because that would just break the entire thing, right? So we make sure to remove all of this trailing and leading white space, clean up the string, and then that's when we append that to the ignore list over here, right? And if there's an error, let's say if error equals s.error and error does not equal to nil, then we return nil. we return the error as well otherwise we return the to ignore list and We return nil for the error and that's all we need to do now with this function We can read the getting more files in Every single project now back up in the in the upload folder function Now we need to create the actual to ignore lists over here, right? So first of all, first of all, let's create the global ignore list, right? the one over here in this ignore keyword in config dot JSON right to build this let's just say to ignore equals make and we will say make a list of strings I ruined the syntax make a list of strings with a length of zero but a capacity for was the capacity for drive dot config dot ignore over here will say length of of drive.config.ignore. This is kind of like an optimization thing. Basically, I'm saying make a list of strings. That's what we need with a length of zero because we don't want a length right now, but a capacity for the amount of elements that we have in the ignore list in the config, right? This ignore list over here, right? Right here. If I instead set the length of this list to that, then it would basically fill it up with empty elements, right? Which we don't need to do, right but instead if i set the capacity to that list right then it will allow us to have that much capacity so we won't need to reallocate space in in this list to add new elements but we also won't need to fill it up with empty elements because we're setting length to zero so yeah a bit of a minor optimization that i'm doing over here anyway we'll say append to ignore and then we'll say drive.config.ignore and use this spread operator over here to add everything in the ignore list in the config to this ignore list that we creating over here So with these two lines of code we basically have the global ignore list over here all set Now we need to add the git ignore list, right? So to do that, let's do a quick check. Let's say drive.config.useGitIgnore. If this is true, then we should add the git ignore list. Otherwise not, right? So a quick check to make sure that that's true. And then we can just say something like git ignore and error equals read git ignore and pass in the folder over here. Make sure to handle the error as well as usual. We'll say log.printf cannot read git ignore. Cannot read git ignore. And we'll upload all files. And then print the error as well over here. Make sure to add a new line as well. Let's say error over here. And that's all we need to do. Awesome. So if you cannot read the get ignore then we'll just upload all files by default right and then we can just say to ignore Equals append to ignore get ignore there we go and now we have everything we need basically now all we need to do is Loop through this to ignore list and just discard everything that matches over here, right? And if we do that, then we're basically done with this feature. So to do this, let's head into the filepad.walkdir function and up top over here I'm just going to loop over the list. I'll say for underscore ignore in range to ignore and let's grab the ignored directory as well the full path of this directory which will be filepad.join folder.path and ignore. there we go so basically if our if our ignored folder is something like client.json then when we add the folder path to it will have an absolute path to it right like something like c slash project slash folder that we're trying to sync slash client.json right we want to have an absolute path over that right so that's what i'm doing over here by using file path.join and then let's create a conditional over here let's say should skip equals ignored dir and check if the path equals to that so we're saying if the path that we're currently on in this walk dir function equals the ignored dir right if the current path that we're on equals the directory that we're trying to ignore then you should skip that directory now along with this let's add an or conditional as well, we want to add a bit of a, we want to handle a little edge case as well over here. Let's say strings.has prefix path ignore dir plus os.path separator. And let's convert this path separator to a string as well over here. And there we go. So basically, let me walk you through the entire conditional real quick. First of all, I'm saying if the path equals the ignored dir, right? So if the current path that we're on equals the directory that we're trying to ignore, then we should obviously skip it, right? That makes sense. Now, along with that, we're checking if the current path that we're on has the prefix of the ignored directory plus a path separator. So basically, we want to be able to ignore the directory even if we're on a subfolder of that directory, right? Something like, if I have something like a, if I want to ignore, let me do this in comments, as well. There we go. If I want to ignore a folder called, I don't know, ignored, right? That's the folder name And if I on the path something like project slash ignored slash file dot txt right If I on this path then this conditional right here is not going to match right because the path is going to be all the way to file dot txt and the ignored directory is going to be project slash ignored right so this is not going to match right which is why we need to handle the edge case over here by using strings dot has prefix path ignored there right if the if the pad that we're currently on which is this has the prefix of project slash ignored plus a patch separator like this slash over here then we can safely ignore that as well right so that's why i add this little extra condition over here right let's remove these comments and now we just use this condition over here right we just say if should skip we'll say log.printf skipping and I'll print the directory that we're skipping over here. Let's say ignore dir or actually we can just say path over here because it's just going to be the same thing, right? And of course, make sure to add a new line as well over here. And now one more thing, we can say if this is a directory, then we should return, what was it? There was a special error, filepad.skipdir and if it is not a directory if it's just a regular file then we can just return nil over here right so basically filepad.skipdir is a special error code over here and if we return this then it will basically skip walking through the entire directory right it won't um try to try to access all the other files in this directory if we're going to just ignore the entire thing right so this is very useful as well otherwise if it's just a file then we just return nil and it can move on to the next file right and that's all we need to do that is all we need to do so let's test this out now so here I am in my Google Drive and you can see I have the client or JSON and the token JSON uploaded over here right which we don't want so what I'm going to do is I'm going to run the entire thing again and this time it should read the gitignore file and refrain from uploading all of these sensitive files right so let's try running this okay the token is expired that makes sense i want to be able to this is a separate feature by the way but i want to be able to refresh the tokens directly right automatically without me having to like do it myself right but um i think i'll build that in a different video for now let's just say force refresh equals true and just run this thing over here there we go once you once you add access to this this app it's gonna redirect to local host which doesn't mean anything and you can just grab this whole code over here in the URL and just take that and paste it over here and there we go now it's starting the process deleted the previous folder created subfolders skipping the git folder skipping the client.json file over here as you can see it's all working right and I think it's almost done yeah it's done and it also skipped uploading the token.json file so perfect this works perfectly let's see what happened on Google Drive as well there we are let's open up this folder and you will see yeah see there is no client.json no token.json none of those files over here right so we were able to ignore all of the files that we don't want to upload and just upload the ones we do want to upload right so yeah this whole thing works and with that as you can see this whole feature works and we're done with the video you can go around and play with this a bit more maybe add a couple more features i don't know but yeah this whole thing works uh in the next video i'm probably going to