之前曾经依赖过 Homebrew Formula 创建过基于 Ruby 的命令行工具。但创建过程繁琐,对于依赖的处理不是很友好而且没办法让其它人依赖特定的版本。既然是做基于 Ruby 的 CLI,那为什么不把它做成一个 gem?

通过 Gem 搭建 CLI

如果我们要创建一个名字叫 CLIGem 的命令行工具,它依赖 gli 这个 gem,它提供一个命令 cg,在执行后会输出一句话 Hello, world!。创建一个这样的 CLI 需要哪些过程呢?

创建

首先执行 bundle gem CLIGem ,相当于执行一个脚手架,它会通过模板帮你创建出一个已经搭建好的框架

添加依赖

打开 CLIGem.gemspec,添加 spec.add_dependency "gli", "~> 2.0" ,这里最好要指定版本号

添加命令行入口

通过修改 .gemspecbindir 还有 executables 字段可以把命令暴露给安装这个 gem 的人,达到成为一个 CLI 的目的。

spec.bindir        = "exe"
spec.executables = "cg"

需要在要目录创建一个目录 exe,添加一个新文件 cg 并添加可执行的权限。cg 的内容如下,

#!/usr/bin/ruby

require 'gli'

puts "Hello, world!"

使用

如果把它发布出去,那通过 gem install CLIGem 安装就可以了

但如果不想发布,要如何安装使用呢?

所幸 gem 提供了通过源码安装的方式。gem build 可以根据一个 gemspec 生成一个 .gem 文件供 gem 安装,所以在拥有源码的情况下,执行以下几句就可以安装了,

gem build CLIGem.gemspec
gem install *.gem

如果别人通过 bundler 来依赖你,那么他可以在工程中的 Gemfile 中这样写,

gem 'CLIGem', :git => '[email protected]:xxx/CLIGem.git', :tag => '1.0.1'

这样,每次 bundle install,依赖就会自动安装成功了

与 Homebrew Formula 的区别(都是通过源码而非发布的安装情况下)

Gem Homebrew Formula
依赖安装、上手容易
版本管理
bundler 友好
安装更新容易

总体来看,如果是使用 ruby 编写 CLI,使用 gem 比使用 Homebrew 搭建更加方便。即使前者安装更新麻烦一些(需要 clone 源码),但可以通过把这些操作封装成 shell 脚本来解决。总体来说,使用 Gem 编写 CLI 体验更好。