天天看点

[brew|Mac]如何将软件发布到Homebrew

开发了一个用于

macOS

的工具软件,如何方便使用者进行安装呢?在

macOS

上比较常用的安装管理工具是brew。以我最近开发的一个用于打通

macOS

docker

容器网络的工具客户端docker-connector为例,说明如何让软件可以通过

brew install

安装。

准备软件

要通过

brew

进行安装,需要提供软件下载地址,下载的可以是源码,也可以是编译好的可执行文件的tar包。我使用了编译好的可执行文件,打成tar包,并且生成SHA256。

$ tar -czf docker-connector-mac.tar.gz docker-connector
$ shasum -a 256 docker-connector-mac.tar.gz | awk '{print $1}' > docker-connector-mac-sha256.txt
           

把编译好的可执行文件打包之后上传到

Github

Releases

中(也可以放到任何能够公共访问的地方),上传之后可以获取下载链接,后续会用到。

https://github.com/wenjunxiao/mac-docker-connector/releases/download/v1.0/docker-connector-mac.tar.gz

准备tap仓库

Homebrew除了核心仓库之外,还支持第三方仓库,如何提交到核心仓库,可以查看官方文档。前期为了方便测试和及时更新,准备自己的第三方仓库。在

Github

新建一个仓库,仓库的名称必须是

homebrew-

开头,后面的名称自定义,安装的时候需要指定该名称,我把仓库命名为homebrew-brew,语言选择

Ruby

。克隆到本地之后新建

$ git clone https://github.com/wenjunxiao/homebrew-brew
$ cd homebrew-brew
$ mkdir Formula
           

后续需要提交软件只需要在

Formula

增加一个

Ruby

文件即可。

准备

Formula

每个软件对应一个

Formula

文件,该文件使用

Ruby

语言,以docker-connector.rb为例,分析一下如何编写。

最基本的结构如下

class DockerConnector < Formula
  desc "软件功能描述"
  homepage "https://github.com/wenjunxiao/mac-docker-connector"
  url "https://github.com/wenjunxiao/mac-docker-connector/releases/download/v1.0/docker-connector-mac.tar.gz"
  sha256 "....."
  version "1.0"
  def install
    bin.install "docker-connector"
  end
end
           

第一行

class DockerConnector < Formula

定了一个

Ruby

的类继承自

Formula

,类的名称可以自定义。必须

end

结尾

desc

属性

desc

是软件的功能描述

homepage

属性

homepage

是软件的主页地址

url

属性

url

是软件的下载地址,用前面准备的下载地址

sha256

属性

sha256

是软件包的

SHA256

用于验证软件包的

version

属性

version

是指定软件版本

install

方法

接下来

def install

是定义了安装行为的方法,必须用

end

结尾。

bin.install

bin.install

是安装可执行文件,后面跟的是软件包中的可执行文件,软件通常会安装(或链接)到

/usr/local/bin/

目录。如果安装包中的的名称与安装之后名称不一致,可以使用

=>

重新指定,比如,把名称

a

修改为

b

bin.install "a" => "b"
           

这是最简单的安装单个可执行文件。

etc.install

如果还有配置文件可以通过

etc.install

安装。

如果安装包没有配置文件,为了初始化话配置文件,可以在安装时生成

(buildpath/"options.conf").write <<~EOS
  # addr 192.168.251.1/24
  # mtu 1400
  # host 127.0.0.1
  # port 2511
  # route 172.17.0.0/16
EOS
etc.install "options.conf" => "docker-connector.conf"
           

以上的代码是在构建目录

buildpath

下生成一个

options.conf

的文件,写入文件的内容是

EOS

扩起来的内容

# addr 192.168.251.1/24
# mtu 1400
# host 127.0.0.1
# port 2511
# route 172.17.0.0/16
           

同样上面由于配置文件名与最终安装的配置文件名不一样所以使用

=>

重命名了,也可以生成的时候就使用相同的名称。

(buildpath/"docker-connector.conf").write <<~EOS
EOS
etc.install "docker-connector.conf"
           

plist

方法

除了安装软件之外,还可以安装对应的服务,以便通过服务管理

plist

方法定义了生成

macOS

服务的

plist

内容。

def plist
  <<~EOS
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
        <key>KeepAlive</key>
        <dict>
          <key>SuccessfulExit</key>
          <false/>
        </dict>
        <key>Label</key>
        <string>#{plist_name}</string>
        <key>ProgramArguments</key>
        <array>
          <string>#{opt_bin}/docker-connector</string>
          <string>-config</string>
          <string>#{etc}/docker-connector.conf</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>WorkingDirectory</key>
        <string>#{var}</string>
        <key>StandardErrorPath</key>
        <string>#{var}/log/docker-connector.log</string>
        <key>StandardOutPath</key>
        <string>#{var}/log/docker-connector.log</string>
      </dict>
    </plist>
  EOS
end
           

其中

ProgramArguments

后的数组中配置了运行服务的命令,

#{opt_bin}

是安装软件的目录,

#{etc}

是配置文件的安装位置,这些都是安装时的变量,安装完成之后会被替换成具体的值。

StandardErrorPath

StandardOutPath

分别表示软件运行的标准错误和标准输出的日志文件。

caveats

方法

def caveats

方法中定义了安装完成之后输出的提示信息,用于引导用户执行正确的操作,系统会有默认的提示信息,也可以添加额外的提示信息,比如用户该执行什么操作来完善配置等

def caveats
  <<~EOS
  For the first time, you can add all the bridge networks of docker to the routing table by the following command:
    docker network ls --filter driver=bridge --format "{{.ID}}" | xargs docker network inspect --format "route {{range .IPAM.Config}}{{.Subnet}}{{end}}" >> #{HOMEBREW_PREFIX}/etc/docker-connector.conf
  Or add the route of network you want to access to following config file at any time:
    #{HOMEBREW_PREFIX}/etc/docker-connector.conf
  Route format is `route subnet`, such as:
    route 172.17.0.0/16
  The route modification will take effect immediately without restarting the service.
  EOS
end
           

安装软件

Formula

提交之后就可以在

macOS

执行

brew install

了,由于是第三方的,所以首次安装之前需要下载仓库,下载时指定用户名和仓库名(不需要

homebrew-

)

$ brew tap wenjunxiao/brew
           

执行安装安装

$ brew install docker-connector
           

也可以通过一个命令进行安装(如果和其他仓库有重名时也可以通过该命令安装)

$ brew install wenjunxiao/brew/docker-connector
           

继续阅读