How To Add Extra Commands To CLI Tools

While this is great for brand new ideas, sometimes all we need is to add an extra feature to an existing tool: in this article we’re going to do just that.

Example

Let’s say that we would like to add a new git feature for grading the current code base (😱):
in order to do so we will create a new gitsubcommand, $ git star, and we’re also going to use ArgumentParser!

For simplicity’s sake, our subcommand will ask for a rating from 1 to 5 as an input, and print it out in the terminal. But there’s truly no limit on what can we can do.

Let’s get started!

Project setup

Naming Convention

The package name doesn’t really matter, however I suggest you to follow name patterns such as git-star, where the prefix is the tool we’re extending, and the postfix is our subcommand, as those are patterns used by similar tools, and also the final name of our binary.

In our example we will do the following:

$ mkdir git-star
$ cd git-star
$ swift package init --type executable

Adding ArgumentParser Dependency

// swift-tools-version:5.1// The swift-tools-version declares the minimum version of Swift required to build this package.importPackageDescriptionletpackage=Package(name:"git-swift",dependencies:[// Dependencies declare other packages that this package depends on..package(url:"https://github.com/apple/swift-argument-parser",from:"0.0.1"),],targets:[// Targets are the basic building blocks of a package. A target can define a module or a test suite.// Targets can depend on other targets in this package, and on products in packages which this package depends on..target(name:"git-swift",dependencies:["ArgumentParser"]),.testTarget(name:"git-swiftTests",dependencies:["git-swift"]),])

The Package.swift content.

main.swift

At this point all is left is to write the actual command, without further ado:

Releasing The Script

The Caveat

When an executable placed in /usr/local/bin/ has a dash - in its name, and the original command (the prefix) accepts subcommands, then we can run our command with and without the dash, which means that we can now run $ git star from anywhere: