Skip to main content

Making a plugin for your Gluegun-powered CLI

Gluegun is a powerful CLI toolbox, but if you want to know what really sets it apart, it's the plugin system. While Commander and Yeoman and other CLI systems have plugin concepts, with gluegun we treat them as first-class citizens.

Let's walk through creating a plugin for a CLI. We'll then use this plugin in a project where we're using this CLI.

Note: if you're experiencing any issues in the tutorial, feel free to let us know in the IR Community Slack. We want this to work really smoothly!

Step 1: Our CLI

We're building out a CLI that prints out system information, called intern. Let's spin this up:

$ yarn global add gluegun
$ gluegun new intern --javascript
$ cd intern
$ yarn
$ yarn link
$ cd ..
$ intern help

You should see the baked-in help for our new CLI. Yay!

Step 2: Create the basic plugin structure

Let's create a plugin that we would use to show system information for macOS. It'll be called intern-macos.

NOTE: This is the naming scheme we recommend for gluegun-powered plugins -- put the name of your CLI, a dash, and then the name of your plugin. Examples: ignite-i18n, solidarity-react-native. We support this naming scheme right out of the box, in fact!

$ mkdir intern-macos
$ cd intern-macos
$ yarn init

At this point, go through yarn's init. It doesn't matter too much what you put here. I just hit enter on everything.

Lastly, add a commands and an extensions folder. Note that with new versions of Gluegun, you can also use a build pipeline and include your commands and extensions in build/commands and build/extensions and Gluegun will still find them.

$ mkdir commands extensions

Step 3: Create a command

We're going to make a command that we'll invoke with intern macos which will display the version of macOS we're currently running.

$ touch commands/macos.js

Open this file, and put the following:

module.exports = {
name: 'macos',
alias: 'osx',
run: async ({ system, print }) => {
const osInfo = await system.run(`defaults read loginwindow SystemVersionStampAsString`)
print.info(osInfo)
},
}

Step 4: Create an extension

While the above is a simple command, if the logic started getting more complex, we'd probably want to move it into an extension. Let's do that here.

In extensions, create a new file called macos-extension.js:

$ touch extensions/macos-extension.js

Edit this file like so:

module.exports = (toolbox) => {
toolbox.internMac = async () => {
return await toolbox.system.run(`defaults read loginwindow SystemVersionStampAsString`)
}
}

This adds a new property to gluegun's awesome toolbox object, called internMac, which is a function that returns the info we need. Since all extensions are loaded automatically, it's available in our command, so let's use it in commands/macos.js:

module.exports = {
name: 'macos',
alias: 'osx',
run: async ({ print, internMac }) => print.info(await internMac()),
}

Step 5: Make a new project

Let's try this out!

cd ..
mkdir my-project
cd my-project
yarn init
yarn add ../intern-macos

Note that we're referencing the plugin from a folder, because we haven't published it to NPM yet. If we have, we'd use yarn add intern-macos like you'd expect.

Now let's kick off our plugin command:

$ intern macos
10.13.1

Let's try the alias:

$ intern macos osx
10.13.1

Yay!

Step 6: Publish to NPM

You can learn how to publish an NPM package here: https://docs.npmjs.com/getting-started/publishing-npm-packages

Once it's published, you can add your new plugin to your project:

$ yarn add intern-macos

After that, the new command should be available on your project like we explored above.

Still have questions? Let us know in the IR Community Slack.

If you'd like to learn more about what plugins are, check out the plugins documentation.