Home  >  Article  >  Backend Development  >  My first CLI with Go

My first CLI with Go

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-09-25 22:08:221059browse

My first CLI with Go

I always felt a bit anxious to write about my experiences. Well, I think I can deal with it now. It was an early morning in August when I decided to write a CLI tool just to "practice" Go as I had learned the basics a few days earlier. I do not watch many tutorials nowadays but I watched Nana's Video on Golang and it was pretty awesome. So, let's jump right in.

The reason

I wanted to experiment with Go to learn the os module. The first thought that came to my mind was to create a turborepo with Golang as a server. Yes, I know that we cannot host it in Vercel, but the idea was to create a fast and secure server with Golang. We can use an API proxy in Vercel to rewrite the requests from the client side. However, you will be required to host your Go server separately in some places like Railway or Render. This doesn't follow the rule of a mono repo architecture, it is just maintaining all the code in a single place and building a strong server. It was named turbo-g (turbo + go).

Well, after creating a template project, I realized that Turbo has some issues with hot reload and many other things. So, eventually, I dropped the idea and moved on to create something else.

When creating this template project, I saw that I had to set up the server manually and I used gofiber as it has express-like functionalities, and as a MERN stack developer, I found it very easy to use. Once I thought to make a server-project generator in Express as well, but they already have one, it is called express-generator. Then I thought there might be the same thing for Fiber as well. But when I searched in GitHub with the topic:go-backend-template, I only found pre-made templates that you can clone and use for your projects. That's when I decided to give it a shot.

The process

Making a CLI with go is fairly simple, as go codes are compiled into a binary executable. But, I didn't know how to create files and folders using the os module. In JavaScript(NodeJs), we can use the fs module to manage files. All thanks to the docs for helping me out. I already knew what a basic backend project looks like in Express and Fiber as well. My approach was very simple. I will create a CLI tool that will use a few flags like --init and --name for the project name and it will generate a project and go.mod with fiber as a dependency.

Then I got stuck in the thing called templates. Templates are a skeleton of a go file. A template holds the content of the file. It was interesting to learn about templates. Then it was easy to take the project name from the flag and create all file folders using os.MkdirAlland parse the templates with the text/template module and get the content to create the files. All the details of these modules can be found in the Golang docs I mentioned above. Then it was done! ? But..

dirs := []string{"cmd", "internal/handlers", "internal/middleware", "internal/models", "internal/routes", "internal/services", "config"}
    for _, dir := range dirs {
        if err := os.MkdirAll(filepath.Join(projectPath, dir), os.ModePerm); err != nil {
            return fmt.Errorf("❗Failed to create directory %s: %w", dir, err)
        }
    }

The problems

  • I found out soon that I wasn't using github.com// as the module name which was a problem I encountered when I was learning about the go modules for the first time. Then I learned about the module path from here. So, what I did to solve the problem is very simple. I just added a -gh flag for users to add their GitHub Username to crate the module assuming the project name is the GitHub repo.

  • Another problem that still exists that is I did not provide any code in the middleware template file and the config template file. Users can use MongoDB or PostgreSQL as a database so it was unnecessary to provide any single or both configs in the template. Well, to fix this I created an issue and anyone reading this blog can contribute to solving this problem. I already figured out a way but this comes down to the third problem.

  • The CLI can take a user input called -db to get the user's choice of databases like MongoDB or PostgreSQL to make a dummy connection in the Config template. But, as the code grows to solve these kinds of problems, the CLI will be unusable. It already has 2 required flags and one optional which are --init, -gh, and -name, and if we add a -db flag it will be a very long command. To solve this problem I am going to modify the CLI as an interactive one like create-next-app. After this change, we can add many options for customization. I am already working on this. So, if you want to contribute, you are welcome. You can find the issue here.

  • The last problem for now is a hot reload module. Whenever we create a fiber app we don't have any change listener by default. If fiber has this already and I do not know about it then forgive me for that I am relatively new to this. If you know anything about this, let me know in the comments. To solve this problem I figured out to include air in the project.

The end

This is the story of Optical . However, the blog intends to let you guys know about the little project and also it is an invitation to contribute to the project if you want.

The journey has just started and it has been very interesting so far. I learned a lot of things and am willing to learn more ahead. This was my first blog here, so if I made any mistake or overlooked something, please ignore that and forgive me. it will be better next time.

Thanks, everyone for reading the blog, give a ⭐ to Optical if you find it interesting. Also, share if you know anyone willing to contribute. Also, if you find any issues or have any ideas for improvement, you can create an issue here

Thanks again.

The above is the detailed content of My first CLI with Go. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn