概要
シェルを使うのはコマンドのオプションが長くなったとき、備忘のためにコマンドの羅列をファイルに記すだけだった。これをもう少し汎用的なものにしたかった。CodeCommitにPRを飛ばすシェルを例にしながら、調べてわかったことを説明します。
この記事を読むことでコマンドの羅列を詰め込んだファイルを実行するだけ(下記)から
bash main.sh
コマンドっぽいものを実行(下記)できるようになるかも
prlauncher --profile stg launch
前提
開発PCがMacなので、Macで動くBashを前提にこの記事を書いています。普段使っているコマンドを詰め込んだスクリプトなので、皆さんの手元では動かないかもしれません。必要なコマンドの一覧を後述するのでインストール後に実行してみてください。
作るもの
CodeCommitにPR飛ばすスクリプトは下記です。使い方は任意のリポジトリに移動してコマンドを叩くとどのブランチからどのブランチへPRを飛ばしたいのかを対話形式で選べるものです。PRを送るとchangeのURLを開いてくれるのでコピペしてレビュアーにコードをレビューしてもらいましょう。
#!/bin/bash
VERSION="$(basename ${0}) version 0.0.1 ";
function usage {
cat <<EOF
----------------------------------------------------------------------
______ __ __ ______ __
| __ \.--.--.| | | | __ \.-----.-----.--.--.-----.-----.| |_
| __/| | || | | | <| -__| _ | | | -__|__ --|| _|
|___| |_____||__|__| |___|__||_____|__ |_____|_____|_____||____|
|__|
_____ __
| |_.---.-.--.--.-----.----.| |--.-----.----.
| | _ | | | | __|| | -__| _|
|_______|___._|_____|__|__|____||__|__|_____|__|
----------------------------------------------------------------------
$(basename ${0}) is a tool for ...
Usage:
$(basename ${0}) [command] [<options>]
The commands are:
launch Launch pull request interactively!
Options:
--version, -v print $(basename ${0}) version
--help, -h print this
EOF
check
}
function version {
echo $VERSION
}
function launch {
cat <<EOF
----------------------------------------------------------------------
______ __ __ ______ __
| __ \.--.--.| | | | __ \.-----.-----.--.--.-----.-----.| |_
| __/| | || | | | <| -__| _ | | | -__|__ --|| _|
|___| |_____||__|__| |___|__||_____|__ |_____|_____|_____||____|
|__|
_____ __
| |_.---.-.--.--.-----.----.| |--.-----.----.
| | _ | | | | __|| | -__| _|
|_______|___._|_____|__|__|____||__|__|_____|__|
----------------------------------------------------------------------
EOF
git remote -v >> /dev/null 2>/dev/null
if [ ! $? = "0" ]; then
echo [ERROR] $(git remote -v)
exit 1;
fi;
repo_name=$(git remote -v |head -n 1|sed 's?.*v1/repos/??'|cut -d ' ' -f1)
read -p "type your title of pull request: " title
branches=($(git ls-remote origin | sed 's?.*refs/heads/??' | tail -n +2))
echo "\nQ1: Which is target_branch ? (\"target_branch\" <- request_branch):"
echo ${branches[@]} | tr ' ' '\n' | nl -v 0
read -p "Select number (0...$((${#branches[@]}-1))): " num
echo ""
target_branch=${branches[$num]}
echo "\n\nQ2: Which is request_branch ? ($target_branch <- \"request_branch\"):"
echo ${branches[@]} | tr ' ' '\n' | nl -v 0
read -p "Select number (0...$((${#branches[@]}-1))): " num
echo ""
request_branch=${branches[$num]}
echo "\n\nQ3: Do you want pull request there branches below?"
echo "----"
echo "repositoryName : $repo_name"
echo "title : $title"
echo "branch : $target_branch <- $request_branch"
echo "description : Comming soon..."
echo "----"
read -p "yes or no :" ans
case "$ans" in
yes)
response=$(aws codecommit create-pull-request --title "$title" --targets repositoryName=$repo_name,sourceReference=$request_branch)
if [ ! $? = "0" ]; then
echo "[ERROR] aws command error";
exit 1;
fi;
echo $response|jq;
pr_id=$(echo $response | jq -r .pullRequest.pullRequestId)
region=$(aws configure get region)
echo "[Success] PullRequestURL is below."
echo "https://${region}.console.aws.amazon.com/codesuite/codecommit/repositories/${repo_name}/pull-requests/${pr_id}/changes?region=${region}"
open https://${region}.console.aws.amazon.com/codesuite/codecommit/repositories/${repo_name}/pull-requests/${pr_id}/changes?region=${region}
;;
no)
echo "OK."
;;
*)
echo "[ERROR] retry please. see you"
exit 1
;;
esac
}
function check_cmd {
if !(type "$1" > /dev/null 2>&1); then
echo "[ERROR] not found command $1. Please install $1."
exit 1;
fi;
}
function check {
check_cmd git
check_cmd aws
check_cmd jq
}
case ${1} in
launch)
$1
;;
help|--help|-h)
usage
;;
version|--version|-v)
version
;;
*)
usage
exit 1
;;
esac
いくつかの部品に分けて説明をしていきます。
#0 コマンドっぽくしたい
なにか色々やりたいことを詰め込んだコマンドの塊を下記で実行するのをまずはやめたいと思います。コマンドっぽくしましょう。
bash main.sh
コマンドっぽさといえば、私は下記のようなものをイメージします。
- どこからでも実行できる
- 使い方が標準出力される
- オプションを設定できる
- サブコマンドがある
- 対話形式でよしなにやりたいことをやってくれる
- ちょっとかわいい標準出力
一つずつ説明していきたいと思います。
#1 どこからでも実行できるようにする
bash main~~.sh~~
まずは実行するときにbash
と.sh
を消しましょう。
下記の通りscriptファイルの先頭に#!bin/bash
と追記します。
#!/bin/bash
echo "prlauncher script"
ファイル名をリネームしましょう
mv main.sh prlauncher
実行権限を与えましょう
chmod +x prlauncher
シンボリックリンクをはりましょう
ln -s /var/local/bin/prlauncher $(pwd)/prlauncher
これでどこからでも実行できます。好きなディレクトリに移動してprlauncherを入力して実行してみてください。
cd ~
prlauncher
下記のように出力されたら成功です。コマンドを修正したいときは、従来どおりのパスのファイルを変更すれば良いです。
prlauncher script
#2 使い方が標準出力されるようにする
コマンドだけ打ち込んだ場合や-h, --help, helpといったサブコマンドを打ち込むと使い方が表示されるようにしましょう。
まずはコマンドを打ち込んだときに使い方が出力されるようにします。
#!/bin/bash
function usage{
cat <<EOF
$(basename ${0}) is a tool for ...
Usage:
$(basename ${0}) [command] [<options>]
The commands are:
launch Launch pull request interactively!
Options:
--version, -v print $(basename ${0}) version
--help, -h print usage
--profile select profile (aws-cli)
EOF
}
usage
usage
というfunctionを定義して、最終行で定義したusage関数を呼び出しています。$(basename ${0})
を用いることで実行しているファイル名を参照することができます。(今回の場合はprlauncherが出力されます)使い方は、自分が忘れたときに思い出せるように書きましょう。
記載した使い方に従って実装を進めていきます。
続きます。