Dominik Zarsky
Dominik Zarsky

Dominik Zarsky

Introducing ingoreinit - A CLI tool for creating gitignores

Introducing ingoreinit - A CLI tool for creating gitignores

Dominik Zarsky's photo
Dominik Zarsky
·Oct 17, 2022·

4 min read

Table of contents

  • The tool
  • Conclusion and future development

Let's talk generating .gitignore files - a file every git repo should have. Some tools for scaffolding projects like create-tauri-app or composer create-project initialize .gitignore for you. But what about applications which do not use these? Like when generating new solution in Visual Studio or creating a new Go app. Many developers tend to manually copy the ignore files from their previous projects or go to github/gitignore to get them. In my opinion, this is very tedious and can be achieved in a simpler and faster way - via the CLI.

This is where ignoreinit comes in.

The tool

I originally wanted to create a tool like this mainly for the aformentioned reasons - it is faster and more comfortable to get your .gitignore from the command line. And as somebody who is always working on new projects, I wanted to simplify my workflow as much as possible.

The tool itself is written in Go, leveraging a library called go-github to fetch gitignores. In the first iteration, it can either download a new gitignore file based on selected language and framework (for now it has to be one of the gitignore files present in the aformentioned github/gitignore repo) or replace existing gitignore by specifying new language and path of the ignore to be replaced.

The flow is as follows:

  • ignoreinit parses the CLI parameters
  • It fetches the list of all available gitignores from the repo
  • Determines whether a .gitignore is available for selected language or framework
  • If it is, ignoreinit downloads the ignore file and creates .gitignore with its contents in the selected directory

The flow is pretty simple. As is the main function which handles the fetching itself, I will include a snippet at the end of the article.

How to get and use ignoreinit

If you find the tool interesting, it can currently be installed in three ways. If you have Go already installed on your machine, you could just do go install github.com/loupeznik/ignoreinit@latest, this should automatically install it and add it to your $PATH (if you have path to Go binaries in your $PATH already). Cloning the repo and building the binary yourself is also a possibility.

If you are Go-less, you can always get it from the Releases page of the Github repo. Binaries for Linux, Windows and MacOS are available. Using the last method, you might want to add the binary to your $PATH (e.g. moving it for example to /usr/local/bin on Linux or appending the folder which the executable resides in to your PATH on Windows).

Usage is pretty straightforward:

ignoreinit <init|replace> <language> <location>

For example:

# Initialize a new .gitignore for Go in current directory
ignoreinit init go
# Initialize a new .gitignore for Python in different directory
ignoreinit init python C:\Dev\my-flask-api
# Replace gitignore in current directory
ignoreinit replace c++

Conclusion and future development

This article briefly introduced the ignoreinit CLI tool for generating .gitignore files conveniently from the commandline. In the future, I would like to enhance the tool to also support .dockerignore files, have more .gitignore repositories available and have the tool available in package managers like snap, apt or chocolatey for smoother installation experience.

If you've made it this far, thanks for reading. Until next time...

P.S. the aformentioned snippet:

func getIgnore(language string, location string, isNew bool) error {
    client := github.NewClient(nil)
    ctx := context.Background()
    options := &github.RepositoryContentGetOptions{}

    _, directoryContent, _, err := client.Repositories.GetContents(ctx, gitOwner, gitRepo, "/", options)

    if err != nil {
        return err
    }

    var url string

    for _, file := range directoryContent {
        if !strings.EqualFold(strings.Split(*file.Name, ".")[0], language) {
            continue
        }

        url = file.GetPath()

        break
    }

    if url == "" {
        return fmt.Errorf("could not find .gitignore for %s", language)
    }

    reader, _, err := client.Repositories.DownloadContents(ctx, gitOwner, gitRepo, url, options)

    if err != nil {
        return err
    }

    defer reader.Close()

    bytes, err := io.ReadAll(reader)

    if err != nil {
        return err
    }

    var file *os.File
    fullPath := path.Join(location, ".gitignore")

    if isNew {
        file, err = os.Create(fullPath)
    } else {
        file, err = os.OpenFile(fullPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
    }

    if err != nil {
        return err
    }

    defer file.Close()

    _, err = file.Write(bytes)

    if err != nil {
        return err
    }

    return nil
}

Cover image credit to Gabriel Heinzer on Unsplash.

Did you find this article valuable?

Support Dominik Zarsky by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
 
Share this