avatarMehran

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

7610

Abstract

Exit(<span class="hljs-number">1</span>) }

fmt.Printf(<span class="hljs-string">"Created folder '%s' and file '%s' within it\n"</span>, folderName, fileName) }, }

<span class="hljs-keyword">if</span> err := rootCmd.Execute(); err != <span class="hljs-literal">nil</span> { fmt.Println(err) os.Exit(<span class="hljs-number">1</span>) } }</pre></div><p id="8675">In this code, we create a <code>rootCmd</code> with the <code>create</code> command. The <code>Run</code> function takes two arguments: the folder name and the file name. It creates the folder using <code>os.MkdirAll</code> and writes a "Hello, world!" message to the specified file using <code>ioutil.WriteFile</code>.</p><p id="31ff">To build and run the CLI application, use the following commands:</p><div id="a068"><pre>go build -o foldercreator ./foldercreator <span class="hljs-string">"myfolder"</span> <span class="hljs-string">"myfile.txt"</span></pre></div><p id="4b8e">This command will create a folder named <code>myfolder</code> and a file named <code>myfile.txt</code> within it containing the message "Hello, world!".</p><h2 id="9476">Create a CLI that lists the most memory-consuming services on your machine</h2><p id="7741">To create a CLI with Golang and Cobra that lists the most memory-consuming services, you can use the <code>ps</code> command on Unix-based systems (Linux and macOS) to get the process list and then parse the output to find the services with the highest memory usage.</p><p id="414c">Please note that this example will only work on Unix-based systems (Linux and macOS) and not Windows.</p><p id="0f38">First, ensure you have created a new Go module and installed the Cobra library, as shown in the previous examples.</p><p id="d86c">Create a file named <code>main.go</code> and add the following code:</p><div id="d906"><pre><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> ( <span class="hljs-string">"fmt"</span> <span class="hljs-string">"github.com/spf13/cobra"</span> <span class="hljs-string">"os"</span> <span class="hljs-string">"os/exec"</span> <span class="hljs-string">"sort"</span> <span class="hljs-string">"strconv"</span> <span class="hljs-string">"strings"</span> )

<span class="hljs-keyword">type</span> Process <span class="hljs-keyword">struct</span> { PID <span class="hljs-type">int</span> Comm <span class="hljs-type">string</span> RSS <span class="hljs-type">int</span> }

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> { rootCmd := &cobra.Command{ Use: <span class="hljs-string">"memtop"</span>, Short: <span class="hljs-string">"A CLI to list the most memory-consuming services"</span>, Long: <span class="hljs-string">This CLI demonstrates how to create a CLI application with Cobra that lists the most memory-consuming services on Unix-based systems.</span>, Run: <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(cmd *cobra.Command, args []<span class="hljs-type">string</span>)</span></span> { psCmd := exec.Command(<span class="hljs-string">"ps"</span>, <span class="hljs-string">"-eo"</span>, <span class="hljs-string">"pid,comm,rss"</span>) output, err := psCmd.Output() <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> { fmt.Printf(<span class="hljs-string">"Error executing ps command: %v\n"</span>, err) os.Exit(<span class="hljs-number">1</span>) }

processes := parsePsOutput(<span class="hljs-type">string</span>(output)) sort.Slice(processes, <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(i, j <span class="hljs-type">int</span>)</span></span> <span class="hljs-type">bool</span> { <span class="hljs-keyword">return</span> processes[i].RSS > processes[j].RSS })

fmt.Printf(<span class="hljs-string">"%-10s %-30s %s\n"</span>, <span class="hljs-string">"PID"</span>, <span class="hljs-string">"Command"</span>, <span class="hljs-string">"RSS (KB)"</span>) <span class="hljs-keyword">for</span> _, p := <span class="hljs-keyword">range</span> processes { fmt.Printf(<span class="hljs-string">"%-10d %-30s %d\n"</span>, p.PID, p.Comm, p.RSS) } }, }

<span class="hljs-keyword">if</span> err := rootCmd.Execute(); err != <span class="hljs-literal">nil</span> { fmt.Println(err) os.Exit(<span class="hljs-number">1</span>) } }

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">parsePsOutput</span><span class="hljs-params">(output <span class="hljs-type">string</span>)</span></span> []Process { lines := strings.Split(output, <span class="hljs-string">"\n"</span>) processes := <span class="hljs-built_in">make</span>([]Process, <span class="hljs-number">0</span>, <span class="hljs-built_in">len</span>(lines)<span class="hljs-number">-1</span>)

<span class="hljs-keyword">for</span> i, line := <span class="hljs-keyword">range</span> lines { <span class="hljs-keyword">if</span> i == <span class="hljs-number">0</span> { <span class="hljs-keyword">continue</span> <span class="hljs-comment">// Skip header line</span> }

fields := strings.Fields(line) <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(fields) != <span class="hljs-number">3</span> { <span class="hljs-keyword">continue</span> }

pid, _ := strconv.Atoi(fields[<span class="hljs-number">0</span>]) rss, _ := strconv.Atoi(fields[<span class="hljs-number">2</span>])

processes = <span class="hljs-built_in">append</span>(processes, Process{ PID: pid, Comm: fields[<span class="hljs-number">1</span>], RSS: rss, }) }

<span class="hljs-keyword">return</span> processes }</pre></div><p id="1289">In this code, we create a <code>rootCmd</code> with the <code>memtop</code> command. The <code>Run</code> function executes the <code>ps</code> command with specific flags to get the process list with PID, command, and RSS (Resident Set Size). The output is then parsed and sorted by memory usage in descending order.</p><p id="6ecb">To build and run the CLI application, use the following commands:</p><div id="7d6c"><pre>go build -o memtop ./memtop</pre></div><p id="8e4a">This command will display the most memory-consuming services on your Unix-based system.</p><p id="5f78">Remember that this example may require modification to work on Windows, as the <code>ps</code> command is unavailable by default. You could use a third-party package to get the process list or use platform-specific APIs to obtain the information.</p><h2 id="348e">Creating a Customizable String Repeater CLI with Flags</h2><div id="4ac7"><pre><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> ( <span class="hljs-string">"fmt"</span> <span class="hljs-string">"github.com/spf13/cobra"</span> <span class="hljs-string">"os"</span> <span class="hljs-string">"strings"</span> )

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> { <span class="hljs-keyword">var</span> count <span class="hljs-type">int</span> <span class="hljs-keyword">var</span> separator <span class="hljs-type">string</span>

rootCmd := &cobra.Command{ Use: <span class="hljs-string">"repeat"</span>, Short: <span class="hljs-string">"A CLI to repeat a string"</span>, Long: <span class="hljs-string">`This CLI demonstrates how to c

Options

reate a CLI application with Cobra that takes a string and repeats it a specified number of times.`</span>, Args: cobra.ExactArgs(<span class="hljs-number">1</span>), Run: <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(cmd *cobra.Command, args []<span class="hljs-type">string</span>)</span></span> { input := args[<span class="hljs-number">0</span>] result := strings.Join(<span class="hljs-built_in">make</span>([]<span class="hljs-type">string</span>, count), input) <span class="hljs-keyword">if</span> count > <span class="hljs-number">0</span> { result = input + separator + result } fmt.Println(result) }, }

rootCmd.Flags().IntVarP(&count, <span class="hljs-string">"count"</span>, <span class="hljs-string">"c"</span>, <span class="hljs-number">1</span>, <span class="hljs-string">"number of times to repeat the string"</span>) rootCmd.Flags().StringVarP(&separator, <span class="hljs-string">"separator"</span>, <span class="hljs-string">"s"</span>, <span class="hljs-string">""</span>, <span class="hljs-string">"separator between repeated strings"</span>)

<span class="hljs-keyword">if</span> err := rootCmd.Execute(); err != <span class="hljs-literal">nil</span> { fmt.Println(err) os.Exit(<span class="hljs-number">1</span>) } }</pre></div><p id="c660">In this code, we create a <code>rootCmd</code> with the <code>repeat</code> command. The <code>Run</code> function takes a string and repeats it based on the provided <code>count</code> flag. We also add a <code>separator</code> flag to specify a separator between the repeated strings.</p><p id="c77d">Build and run the CLI application</p><div id="a04f"><pre>go build -o repeatcli ./repeatcli --<span class="hljs-built_in">help</span></pre></div><p id="1b45">This command will display the help text for the CLI!</p><div id="2208"><pre>./repeatcli <span class="hljs-string">"Hello, world!"</span> --count 3 --separator <span class="hljs-string">", "</span></pre></div><p id="74b1">This command will repeat the input string “Hello, world!” three times with a comma and space as the separator, resulting in the following output:</p><div id="3b7d"><pre><span class="hljs-title class_">Hello</span>, world!, <span class="hljs-title class_">Hello</span>, world!, <span class="hljs-title class_">Hello</span>, world!</pre></div><h1 id="ce8b">Making your CLI available to others</h1><p id="b7a0">For others to use your CLI, you must take two steps explained here.</p><ol><li>Building</li><li>Distributing</li></ol><h2 id="4044">Building CLI application</h2><p id="2f05">Building and registering a CLI application involves two main steps: building the binary for your target platforms and distributing your application so that users can easily install and use it. Here’s a step-by-step guide on how to achieve this:</p><ol><li>Building the binary:</li></ol><p id="ea8b">You can cross-compile your Go program to build the binary for your target platforms (e.g., macOS, Windows, and Linux). We’ve built the binary for the current platform in the previous examples. To build for other platforms, set the <code>GOOS</code> and <code>GOARCH</code> environment variables before building.</p><p id="5240">For example, to build for macOS (amd64), Windows (amd64), and Linux (amd64), you can use the following commands:</p><div id="be9e"><pre><span class="hljs-comment"># macOS (amd64)</span> <span class="hljs-attr">GOOS</span>=darwin GOARCH=amd64 go build -o mycli-mac

<span class="hljs-comment"># Windows (amd64)</span> <span class="hljs-attr">GOOS</span>=windows GOARCH=amd64 go build -o mycli-windows.exe

<span class="hljs-comment"># Linux (amd64)</span> <span class="hljs-attr">GOOS</span>=linux GOARCH=amd64 go build -o mycli-linux</pre></div><p id="3961">These commands will create three separate macOS, Windows, and Linux binaries.</p><h2 id="f3d5">Distributing the CLI application</h2><p id="e130">To publish a package to Homebrew, you must create a Homebrew formula and submit it to a Homebrew tap. Homebrew taps are repositories containing formulae that users can install via the <code>brew tap</code> command. You can either contribute your formula to the main Homebrew repository or create your own tap.</p><p id="c202">Here’s a step-by-step guide on how to create and publish a package to Homebrew using your own tap:</p><ol><li>Create a new GitHub repository called <code>homebrew-tap</code>: Replace <code>tap</code> with a descriptive name for your tap, such as <code>homebrew-mytools</code> for a collection of your tools.</li><li>Create a new file in the repository: Name the file with the format <code>your-tool.rb</code>, where <code>your-tool</code> is the name of your CLI application. This file is a formula that describes how to install your application using Homebrew.</li><li>Add the formula content: Write the formula for your CLI application. Here’s an example template:</li></ol><div id="0b2b"><pre><span class="hljs-keyword">class</span> <span class="hljs-title class_">YourTool</span> < <span class="hljs-title class_ inherited__">Formula</span> desc <span class="hljs-string">"A short description of your CLI application"</span> homepage <span class="hljs-string">"https://github.com/YOUR_USERNAME/your-tool"</span> url <span class="hljs-string">"https://github.com/YOUR_USERNAME/your-tool/releases/download/v1.0.0/your-tool-mac.tar.gz"</span> sha256 <span class="hljs-string">"YOUR_MAC_BINARY_SHA256"</span> version <span class="hljs-string">"1.0.0"</span> license <span class="hljs-string">"MIT"</span>

<span class="hljs-keyword">def</span> <span class="hljs-title function_">install</span> bin.install <span class="hljs-string">"your-tool"</span> <span class="hljs-keyword">end</span>

test <span class="hljs-keyword">do</span> system <span class="hljs-string">"<span class="hljs-subst">#{bin}</span>/your-tool"</span>, <span class="hljs-string">"--version"</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span></pre></div><p id="fad5">Replace <code>YourTool</code>, <code>YOUR_USERNAME</code>, and other placeholders with the appropriate values for your CLI application. Update the <code>url</code> to point to the macOS binary in your release, and replace <code>YOUR_MAC_BINARY_SHA256</code> it with the SHA256 hash of the macOS binary. You can calculate the hash using the <code>shasum</code> command:</p><div id="8a65"><pre>shasum -<span class="hljs-selector-tag">a</span> <span class="hljs-number">256</span> your-tool-mac<span class="hljs-selector-class">.tar</span><span class="hljs-selector-class">.gz</span></pre></div><p id="7bf7">4. Commit and push the changes: Save the formula file and push it to the GitHub repository.</p><p id="e69c">5. Inform users how to install your CLI application: Users can now install your CLI application using Homebrew by running:</p><div id="813b"><pre>brew tap YOUR_USERNAME/tap brew install your-tool</pre></div><p id="0013">Replace <code>YOUR_USERNAME</code> and <code>your-tool</code> with your GitHub username and your CLI application's name, respectively.</p><p id="4373">Following these steps, you’ll create a Homebrew tap and publish your package to it, making it easy for users to install and update your CLI application on macOS.</p><p id="fcda">If your package is of general interest to the Homebrew community, you can submit it to the main Homebrew repository by creating a pull request. However, creating and maintaining your tap is recommended for personal projects or less widely-used tools.</p></article></body>

Create CLI in Go and Publish it to Homebrew

Elevate Your Go CLI Game: Share Your Tool with the World on Homebrew

Generated using Lexica

Introduction

This easy-to-follow blog post will explain some basic examples of creating a Command Line Interface (CLI) using Golang and the Cobra package. After that, I’ll guide you on preparing your package and publishing it on Homebrew for others to use.

Cobra Lib

Cobra is a popular library in Golang that provides a simple interface for creating command-line interface (CLI) applications. Steve Francia, the same person behind the Hugo static site generator and Viper configuration management library, created it.

Cobra offers a straightforward way to create robust and well-structured CLI applications with support for subcommands, flags, and argument parsing. It also makes generating help documentation and auto-completion scripts for various shells easy.

Some key features of the Cobra library include:

  1. Command handling: Easily define commands, subcommands, and their individual actions. Cobra provides a hierarchical command structure that allows you to create complex CLI applications with a transparent organization.
  2. Flags and arguments: Cobra has built-in support for parsing flags (options), and arguments are passed to the commands. It handles both global and local flags, making it easy to manage different options for different commands.
  3. Configuration management: Cobra integrates seamlessly with the Viper library, allowing you to manage your application’s configuration through various sources like configuration files, environment variables, and command-line flags.
  4. Auto-generated help and usage messages: Cobra automatically generates help and usage messages for your CLI application based on the commands, flags, and descriptions you define.
  5. Auto-completion: Cobra supports generating shell auto-completion scripts for Bash, Zsh, Fish, and PowerShell, making it easier for users to interact with your CLI application.

Let’s start

Creating a simple hello world CLI

First, create a new Go module.

go mod init mycli

Then, install the Cobra library:

go get -u github.com/spf13/cobra

Now, create a file named main.go And add the following code:

package main

import (
 "fmt"
 "github.com/spf13/cobra"
 "os"
)

func main() {
 rootCmd := &cobra.Command{
  Use:   "greet",
  Short: "A CLI to demonstrate Cobra usage",
  Long:  `This CLI demonstrates how to create a CLI application with Cobra.`,
  Args:  cobra.MinimumNArgs(1),
  Run: func(cmd *cobra.Command, args []string) {
   fmt.Printf("Greetings, %s!\n", args[1])
  },
 }

 helloCmd := &cobra.Command{
  Use:   "hello",
  Short: "Prints a 'Hello, world!' message",
  Run: func(cmd *cobra.Command, args []string) {
   fmt.Println("Hello, world!")
  },
 }

 rootCmd.AddCommand(helloCmd)

 if err := rootCmd.Execute(); err != nil {
  fmt.Println(err)
  os.Exit(1)
 }
}

In this code, we create a rootCmd with the greet command and a helloCmd with the greet hello command. We add the helloCmd as a subcommand to the rootCmd using the AddCommand method. Finally, we execute the rootCmd and handle any errors.

To build and run the CLI application, use the following commands:

go build -o mycli                                                                                                                                                                        ░▒▓ ✔  vidispine_cv  
./mycli "Your Name" 
./mycli hello

The first command will greet you with “Greetings, Your Name!”. The second command will print, “Hello, world!”.

Building a Simple File and Folder Creator CLI

This application has a single command, create which takes two arguments: the folder name and the file name.

First, ensure you have created a new Go module and installed the Cobra library, as shown in the previous example.

Create a file named main.go and add the following code:

package main

import (
 "fmt"
 "github.com/spf13/cobra"
 "io/ioutil"
 "os"
)

func main() {
 rootCmd := &cobra.Command{
  Use:   "create",
  Short: "A CLI to create a folder and a text file within it",
  Long: `This CLI demonstrates how to create a CLI application with Cobra
that creates a folder and a text file within that folder.`,
  Args: cobra.ExactArgs(2),
  Run: func(cmd *cobra.Command, args []string) {
   folderName := args[0]
   fileName := args[1]

   err := os.MkdirAll(folderName, 0755)
   if err != nil {
    fmt.Printf("Error creating folder: %v\n", err)
    os.Exit(1)
   }

   filePath := fmt.Sprintf("%s/%s", folderName, fileName)
   err = ioutil.WriteFile(filePath, []byte("Hello, world!\n"), 0644)
   if err != nil {
    fmt.Printf("Error creating file: %v\n", err)
    os.Exit(1)
   }

   fmt.Printf("Created folder '%s' and file '%s' within it\n", folderName, fileName)
  },
 }

 if err := rootCmd.Execute(); err != nil {
  fmt.Println(err)
  os.Exit(1)
 }
}

In this code, we create a rootCmd with the create command. The Run function takes two arguments: the folder name and the file name. It creates the folder using os.MkdirAll and writes a "Hello, world!" message to the specified file using ioutil.WriteFile.

To build and run the CLI application, use the following commands:

go build -o foldercreator
./foldercreator "myfolder" "myfile.txt"

This command will create a folder named myfolder and a file named myfile.txt within it containing the message "Hello, world!".

Create a CLI that lists the most memory-consuming services on your machine

To create a CLI with Golang and Cobra that lists the most memory-consuming services, you can use the ps command on Unix-based systems (Linux and macOS) to get the process list and then parse the output to find the services with the highest memory usage.

Please note that this example will only work on Unix-based systems (Linux and macOS) and not Windows.

First, ensure you have created a new Go module and installed the Cobra library, as shown in the previous examples.

Create a file named main.go and add the following code:

package main

import (
 "fmt"
 "github.com/spf13/cobra"
 "os"
 "os/exec"
 "sort"
 "strconv"
 "strings"
)

type Process struct {
 PID  int
 Comm string
 RSS  int
}

func main() {
 rootCmd := &cobra.Command{
  Use:   "memtop",
  Short: "A CLI to list the most memory-consuming services",
  Long: `This CLI demonstrates how to create a CLI application with Cobra
that lists the most memory-consuming services on Unix-based systems.`,
  Run: func(cmd *cobra.Command, args []string) {
   psCmd := exec.Command("ps", "-eo", "pid,comm,rss")
   output, err := psCmd.Output()
   if err != nil {
    fmt.Printf("Error executing ps command: %v\n", err)
    os.Exit(1)
   }

   processes := parsePsOutput(string(output))
   sort.Slice(processes, func(i, j int) bool {
    return processes[i].RSS > processes[j].RSS
   })

   fmt.Printf("%-10s %-30s %s\n", "PID", "Command", "RSS (KB)")
   for _, p := range processes {
    fmt.Printf("%-10d %-30s %d\n", p.PID, p.Comm, p.RSS)
   }
  },
 }

 if err := rootCmd.Execute(); err != nil {
  fmt.Println(err)
  os.Exit(1)
 }
}

func parsePsOutput(output string) []Process {
 lines := strings.Split(output, "\n")
 processes := make([]Process, 0, len(lines)-1)

 for i, line := range lines {
  if i == 0 {
   continue // Skip header line
  }

  fields := strings.Fields(line)
  if len(fields) != 3 {
   continue
  }

  pid, _ := strconv.Atoi(fields[0])
  rss, _ := strconv.Atoi(fields[2])

  processes = append(processes, Process{
   PID:  pid,
   Comm: fields[1],
   RSS:  rss,
  })
 }

 return processes
}

In this code, we create a rootCmd with the memtop command. The Run function executes the ps command with specific flags to get the process list with PID, command, and RSS (Resident Set Size). The output is then parsed and sorted by memory usage in descending order.

To build and run the CLI application, use the following commands:

go build -o memtop
./memtop

This command will display the most memory-consuming services on your Unix-based system.

Remember that this example may require modification to work on Windows, as the ps command is unavailable by default. You could use a third-party package to get the process list or use platform-specific APIs to obtain the information.

Creating a Customizable String Repeater CLI with Flags

package main

import (
 "fmt"
 "github.com/spf13/cobra"
 "os"
 "strings"
)

func main() {
 var count int
 var separator string

 rootCmd := &cobra.Command{
  Use:   "repeat",
  Short: "A CLI to repeat a string",
  Long: `This CLI demonstrates how to create a CLI application with Cobra
that takes a string and repeats it a specified number of times.`,
  Args: cobra.ExactArgs(1),
  Run: func(cmd *cobra.Command, args []string) {
   input := args[0]
   result := strings.Join(make([]string, count), input)
   if count > 0 {
    result = input + separator + result
   }
   fmt.Println(result)
  },
 }

 rootCmd.Flags().IntVarP(&count, "count", "c", 1, "number of times to repeat the string")
 rootCmd.Flags().StringVarP(&separator, "separator", "s", "", "separator between repeated strings")

 if err := rootCmd.Execute(); err != nil {
  fmt.Println(err)
  os.Exit(1)
 }
}

In this code, we create a rootCmd with the repeat command. The Run function takes a string and repeats it based on the provided count flag. We also add a separator flag to specify a separator between the repeated strings.

Build and run the CLI application

go build -o repeatcli
./repeatcli --help

This command will display the help text for the CLI!

./repeatcli "Hello, world!" --count 3 --separator ", "

This command will repeat the input string “Hello, world!” three times with a comma and space as the separator, resulting in the following output:

Hello, world!, Hello, world!, Hello, world!

Making your CLI available to others

For others to use your CLI, you must take two steps explained here.

  1. Building
  2. Distributing

Building CLI application

Building and registering a CLI application involves two main steps: building the binary for your target platforms and distributing your application so that users can easily install and use it. Here’s a step-by-step guide on how to achieve this:

  1. Building the binary:

You can cross-compile your Go program to build the binary for your target platforms (e.g., macOS, Windows, and Linux). We’ve built the binary for the current platform in the previous examples. To build for other platforms, set the GOOS and GOARCH environment variables before building.

For example, to build for macOS (amd64), Windows (amd64), and Linux (amd64), you can use the following commands:

# macOS (amd64)
GOOS=darwin GOARCH=amd64 go build -o mycli-mac

# Windows (amd64)
GOOS=windows GOARCH=amd64 go build -o mycli-windows.exe

# Linux (amd64)
GOOS=linux GOARCH=amd64 go build -o mycli-linux

These commands will create three separate macOS, Windows, and Linux binaries.

Distributing the CLI application

To publish a package to Homebrew, you must create a Homebrew formula and submit it to a Homebrew tap. Homebrew taps are repositories containing formulae that users can install via the brew tap command. You can either contribute your formula to the main Homebrew repository or create your own tap.

Here’s a step-by-step guide on how to create and publish a package to Homebrew using your own tap:

  1. Create a new GitHub repository called homebrew-tap: Replace tap with a descriptive name for your tap, such as homebrew-mytools for a collection of your tools.
  2. Create a new file in the repository: Name the file with the format your-tool.rb, where your-tool is the name of your CLI application. This file is a formula that describes how to install your application using Homebrew.
  3. Add the formula content: Write the formula for your CLI application. Here’s an example template:
class YourTool < Formula
  desc "A short description of your CLI application"
  homepage "https://github.com/YOUR_USERNAME/your-tool"
  url "https://github.com/YOUR_USERNAME/your-tool/releases/download/v1.0.0/your-tool-mac.tar.gz"
  sha256 "YOUR_MAC_BINARY_SHA256"
  version "1.0.0"
  license "MIT"

  def install
    bin.install "your-tool"
  end

  test do
    system "#{bin}/your-tool", "--version"
  end
end

Replace YourTool, YOUR_USERNAME, and other placeholders with the appropriate values for your CLI application. Update the url to point to the macOS binary in your release, and replace YOUR_MAC_BINARY_SHA256 it with the SHA256 hash of the macOS binary. You can calculate the hash using the shasum command:

shasum -a 256 your-tool-mac.tar.gz

4. Commit and push the changes: Save the formula file and push it to the GitHub repository.

5. Inform users how to install your CLI application: Users can now install your CLI application using Homebrew by running:

brew tap YOUR_USERNAME/tap
brew install your-tool

Replace YOUR_USERNAME and your-tool with your GitHub username and your CLI application's name, respectively.

Following these steps, you’ll create a Homebrew tap and publish your package to it, making it easy for users to install and update your CLI application on macOS.

If your package is of general interest to the Homebrew community, you can submit it to the main Homebrew repository by creating a pull request. However, creating and maintaining your tap is recommended for personal projects or less widely-used tools.

Golang
Software Development
Command Line
Engineering
Programming
Recommended from ReadMedium