Homebrewの自作コマンドの作成は様々な言語で実装された記事がありました。ここではShellScriptでHomebrewのコマンドを作成します。
今回は普段管理するライブラリの数が増えて大変になってきていたために必要に感じてgit-pulls
というコマンドを作成しました。これは指定したディレクトリ以下のレポジトリを一括でgit pull
してくれるHomebrewのコマンドを作成しました。
https://github.com/hayashier/git-pulls
作成コマンドの利用方法
以下の2つのコマンドを入力するだけで利用できるようになります。
$ brew tap hayashier/git-pulls
$ brew install git-pulls
利用方法は以下のように一括でgit pull
するパスを指定します。除外するパスも-e
オプションでカンマ区切りで複数指定できます。
$ git-pulls -h
Usage: git-pulls [-h] [-e /exclusivePath1/to,/exclusivePath2/to,/exclusivePath3/to ] /path/to
例えば、git-pulls ./
のようにコマンドを打つと以下のように一括でgit pull
してくれます。
$ git-pulls ./
Start pulling all git project in /Users/hayashier/repository/.
Exclude path: []
/Users/hayashier/repository/me/sample-repository1
Already up-to-date.
/Users/hayashier/repository/me/sample-repository2
Already up-to-date.
/Users/hayashier/repository/me/sample-repository3
Already up-to-date.
-e
オプションで除外するパスも指定できます。またカンマ区切りで除外するパスを複数指定もできます。
$ git-pulls -e me ./
Start pulling all git project in /Users/hayashier/repository/
Exclude path: me
/Users/hayashier/repository/me/sample-repository1
Passing...
/Users/hayashier/repository/me/sample-repository2
Passing...
/Users/hayashier/repository/me/sample-repository3
Passing...
/Users/hayashier/repository/team1/sample-repository1
Already up-to-date.
/Users/hayashier/repository/team2/sample-repository2
Already up-to-date.
Homebrewコマンドの作成
コマンドのプロジェクト作成
1.ディレクトリを作成します。
$ mkdir -p git-pulls/bin
$ cd git-pulls
必要なファイルを編集します。
$ vim bin/git-pulls
#!/bin/bash
GIT_PULLS_VESION="0.0.1"
function contains() {
target=$1
shift
paths=$(echo $@ | tr -s ' ' ' ')
if [ "${paths[1]}" == " " ]; then
flag=$(echo $target | grep ${paths[0]})
if [[ -n $flag ]]; then
return 0
fi
else
for ((i=0;i < ${#paths[@]};i++)) {
if [ ${paths[$i]} == [] ]; then
continue
fi
flag=$(echo $target | grep ${paths[$i]})
if [[ -n $flag ]]; then
return 0
fi
}
fi
return 1
}
function formArrayPaths() {
exclude_paths=$(echo $1 | tr -s ',' ' ')
for ((i=0;i < ${#exclude_paths[@]};i++)) {
path=${exclude_paths[$i]}
flag=$(echo $path | grep $EXECUTING_PLACE)
if [ -n $flag ] && [ $i -ne 0 ] && ([ ${path:0:1} == "/" ] || [ ${path:0:1} == "~" ]); then
num=$(( ${#path} - 1))
exclude_paths[$i]="$EXECUTING_PLACE${path:1:num}"
fi
}
echo ${exclude_paths[@]}
}
if [ -z $1 ]; then
echo 'Usage: git-pulls [-h] [-e /exclusivePath1/to,/exclusivePath2/to,/exclusivePath3/to ] /path/to'
exit
fi
EXECUTING_PLACE=$PWD
trap "cd $EXECUTING_PLACE && exit" {1,2,3,15}
FLAG=true
origin=$HOME
exclude_paths=[]
if [ ${1:0:1} != "-" ]; then
origin=$1
shift 1
FLAG=false
fi
while getopts ":e:hv" OPT ;
do
case $OPT in
e)
result=$(formArrayPaths $OPTARG)
exclude_paths=${result[@]}
;;
h)
echo 'Usage: git-pulls [-h] [-e /exclusivePath1/to,/exclusivePath2/to,/exclusivePath3/to ] /path/to'
exit
;;
v)
echo "git-pulls version $GIT_PULLS_VESION"
exit
;;
esac
done
SHIFT_NUM=$((OPTIND - 2))
if [ $SHIFT_NUM -gt 0 ]; then
shift $SHIFT_NUM
fi
if $FLAG; then
shift 1
origin=$1
fi
if [ ${origin:0:1} != "/" ] && [ ${origin:0:1} != "~" ]; then
origin="$PWD/$origin"
fi
echo "Start pulling all git project in $origin."
if [ -n $exclusive_path ]; then
echo "Exclude path: ${exclude_paths[@]}"
fi
find $origin -type d -name .git | xargs -n 1 dirname | sort | while read line; do echo $line ; contains $line ${exclude_paths[@]}; if [ $? -eq 0 ]; then echo "Passing..."; continue; fi && cd $line && git pull && cd $origin; done
$ vim README.md
# git-pulls
`git-pulls` command pulls all git repositories under specified path.
# Install (OSX)
$ brew tap hayashier/git-pulls
$ brew install git-pulls
# Usage
$ git-pulls [-v] [-h] [-e /exclusivePath1/to,/exclusivePath2/to,/exclusivePath3/to ] /path/to
## Options
-v : Display version
-h : Display usage
-e : Specify path which exclude paths. If you specify multiple paths, enumerate paths separated by comma
予めGitHubにgit-pulls
というレポジトリを作成しておき、これにpushします。
$ git init
$ git add ./
$ git commit -m "first commit"
$ git remote add origin https://github.com/hayashier/git-pulls.git
$ git push -u origin master
tag付けをしてpushします。
$ git tag 0.0.1
$ git push origin 0.0.1
Formulaの作成
Formulaを作成します。ファイル名は[アプリケーション名].rbです。ここではアプリケーション名はgit-pullsとなります。
1.ディレクトリを作成して移動します。
$ mkdir homebrew-git-pulls && cd $_
2.Formulaを作成して編集します。
$ brew create https://github.com/hayashier/git-pulls.git
$ cp /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/git-pulls.rb git-pulls.rb
$ vim git-pulls.rb
Formulaは以下の通りとなります。
REPOSITORY_URL="https://github.com/hayashier/git-pulls".freeze
HOMEBREW_GITPULLS_VERSION="0.0.1".freeze
class GitPulls < Formula
desc "Pulls all git repository under specified paths."
homepage REPOSITORY_URL
url "#{REPOSITORY_URL}/archive/#{HOMEBREW_GITPULLS_VERSION}.tar.gz"
sha256 "ed3b6451a05567505bd718db8fdf343f47e97d70fc7d4d92e7f5cb3c9532b753"
head "#{REPOSITORY_URL}.git", :tag => HOMEBREW_GITPULLS_VERSION
def install
bin.install "bin/git-pulls"
end
test do
system "false"
end
end
なお、sha256の値はtag付したバージョンのtar.gz
の形式のファイルを以下のようなURLからダウンロードしてきます。
https://github.com/<ユーザ名>/git-pulls/releases
そして、openssl
コマンドを用いて以下のようにファイルのハッシュ値を調べます。ハッシュ値はxxxxxx
に当たる部分となります。
$ openssl dgst -sha256 ~/Downloads/git-pulls-0.0.1.tar.gz
SHA256(homebrew-git-pulls-0.0.1.zip)= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
予めGitHubにhomebrew-git-pulls
というレポジトリを作成しておき、これにpushします。
レポジトリ名をhomebrew-
から始まるものでないといけないので注意。
$ git init
$ git add ./
$ git commit -m "first commit"
$ git remote add origin https://github.com/hayashier/homebrew-git-pulls.git
$ git push -u origin master
利用してみる
作成したコマンドは他のユーザも以下のコマンドでインストールできます。
$ brew tap hayashier/git-pulls
$ brew install hayashier/git-pulls
注意点
- 同じバージョンでタグを切り直したとき場合のインストール方法
同じバージョンでタグを切り直したときはアンインストールした上でキャッシュを消しておく。
$ brew uninstall git-pulls
$ rm /Users/hayashier/Library/Caches/Homebrew/git-pulls-0.0.1.zip
改めてインストールします。
$ brew install git-pulls
- 古いバージョンをインストールしていて新しいバージョンをインストールする場合のインストール方法
$ brew uninstall git-pulls
$ brew unlink git-pulls
改めてインストールします。
$ brew install git-pulls
Formulaの構文チェック
brew audit
コマンドでFormulaの構文チェックを行うことができます。
$ brew audit --strict git-pulls
hayashier/git-pulls/git-pulls:
* `version` (line 10) should be put before `checksum` (line 8)
* Stable: version 0.0.1 is redundant with version scanned from URL
* Stable: Use GitHub tarballs rather than zipballs (url is https://github.com/hayashier/homebrew-git-pulls/archive/0.0.2.zip).
* Description shouldn't include the formula name
* C: 1: col 16: Freeze mutable objects assigned to constants.
* C: 1: col 16: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
* C: 2: col 27: Freeze mutable objects assigned to constants.
* C: 2: col 27: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
* C: 9: col 41: Prefer `to_s` over string interpolation.
* C: 10: col 11: Prefer `to_s` over string interpolation.
Error: 10 problems in 1 formula
コマンド実行時のFormulaが以下の状態のときの修正方法について説明します。
REPOSITORY_URL='https://github.com/hayashier/git-pulls'
HOMEBREW_GITPULLS_VERSION='0.0.1'
class GitPulls < Formula
desc "git-pulls command pulls all git repository under specified paths."
homepage "#{REPOSITORY_URL}/README.md"
url "#{REPOSITORY_URL}/archive/#{HOMEBREW_GITPULLS_VERSION}.zip"
sha256 "04777124c8e1ef8b3ba2d884f91ad47378437611b2b1349e730ef85913c2fa30"
head "#{REPOSITORY_URL}.git", :tag => "#{HOMEBREW_GITPULLS_VERSION}"
version "#{HOMEBREW_GITPULLS_VERSION}"
def install
bin.install "bin/git-pulls"
end
test do
system "false"
end
end
Stable: version 0.0.1 is redundant with version scanned from URL
URLにバージョンが含まれているのでversionは冗長だからいらない。
`version` (line 10) should be put before `checksum` (line 8)
バージョンは消すからこれは無視。
Stable: Use GitHub tarballs rather than zipballs (url is https://github.com/hayashier/homebrew-git-pulls/archive/0.0.1.zip).
.zip
じゃなくて.tar.gz
で圧縮したものを指定する。
Freeze mutable objects assigned to constants.
文字列に.freeze
をつけて可変でないようにする
Prefer double-quoted strings unless you need single quotes
定数はシングルクオテーションじゃなくてダブルクオテーション
Prefer `to_s` over string interpolation.
"#{CONSTANT}"
のようにしているところをCONSTANT
とする。
以上となります。
--new-formula
オプションでさらに厳格に
$ brew audit --strict --new-formula git-pulls
hayashier/git-pulls/git-pulls:
* The URL https://github.com/hayashier/homebrew-git-pulls/README.md is not reachable (HTTP status code 404)
* GitHub repository not notable enough (<20 forks, <20 watchers and <50 stars)
* GitHub repository too new (<30 days old)
Error: 3 problems in 1 formula
The URL https://github.com/hayashier/homebrew-git-pulls/README.md is not reachable (HTTP status code 404)
アクセス可能なURLを指定する。
GitHub repository not notable enough (<20 forks, <20 watchers and <50 stars)
20フォーク以上、または20watcher以上、もしくは50スター以上
GitHub repository too new (<30 days old)
レポジトリ作成から30日以上
参考
http://tbpgr.hatenablog.com/entry/2016/07/08/015327
http://girigiribauer.com/archives/20161004/
http://qiita.com/masawada/items/484bbf83ef39cad7af74
http://qiita.com/sakajunquality/items/48b5138986056eb4b49c