- 投稿日:2019-12-14T23:12:43+09:00
Git/Githubをワンライナーで扱うCLIツールを作った話【Go言語】【cobra】
はじめに
golangとcobraを使ってGit/Githubをワンライナーで扱うCLIツールを作成しました。
前半で導入方法や使い方、後半でcobraでCLIツールを作成する方法(WIP at 2019/12/14)について扱います。対象読者
- golangでCLIツール作ってみたい人
- CLIを使って業務改善したい人
- エンジニアな人
リポジトリ
こちらからどうぞ↓
https://github.com/HiroyukiYagihashi/toolbox導入方法
golangの動作環境があれば下記で動くと思います。
$ go get github.com/HiroyukiYagihashi/tooland/gh $ go install $GOPATH/src/github.com/HiroyukiYagihashi/toolbox/gh※
gitコマンドとhubコマンドに依存
していますので、こちらもインストールしてください。
(gitは入れてるけどhubは入れてないって方が多いのでは)
MacOSユーザーかつパッケージマネージャに特にこだわりがなければ下記でインストールできると思います。
違う方は調べてみてください。$ brew install git && brew install hub使い方
下記コマンドで確認できます。
$ gh --help Usage: gh [flags] Flags: -a, --add strings add -c, --cm string commit -m --config string config file (default is $HOME/.gh.yaml) -b, --cop string checkout -b and push -h, --help help for gh -o, --open hub browse -p, --push push下記使用例になります。
$ gh -a app/ -c “Create function” -p -o // app以下をadd、コミットメッセージ”Create function”でcommit、push、該当リポジトリをブラウザで開く $ gh -o // オプション単体でも動作します(挙動は該当リポジトリをブラウザで開く) $ gh -b feature/1/create_function // feature/1/create_functionブランチを切ってリモートに反映cobraでCLIツールを作成する方法(WIP)
需要があったら書こうかなと思ってます。
(個人的にはこの記事に10いいねくらいついたら書くつもりです)それまでは下記を参考にしてください。
https://github.com/spf13/cobra
- 投稿日:2019-12-14T21:29:47+09:00
macOS CatalinaにUpdateしたら, gitの補完が効かなくなったので直した
macOSのアップデートをして
macOS Catalina
に変更した時に,terminalでのgithubの補完機能が働かなくなってしまったので,修正をしました.というより,一から導入したので,その話をします.OSのアップデートをすると,ディレクトリの構成などが変わる場合があります.私はgitのterminalでの補完機能を次のディレクトリから呼び出していました.
/Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash
/Library/Developer/CommandLineTools/usr/share/git-core/git-prompt.sh
OSのアップデートをしたら,上記のファイルがなくなったみたいなので,本記事では,1から補完機能を導入することにしました.
1から導入する
- 使用した環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.2 BuildVersion: 19C57ファイルの準備
- git-prompt.shのダウンロード
wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -O ~/.git-prompt.sh
- git-completion.bashのダウンロード
wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -O ~/.git-completion.bashそれぞれのファイルは,
~/
に保存されています.vim ~/.git-prompt.sh
とvim .git-completion.bash
で内容を確認することができます..bashrcに設定
次に,bashrcの設定を行います.
vim ~/.bashrc
に次を追加してくださいsource ~/.git-prompt.sh source ~/.git-completion.bash追加したら,
.bashrc
を保存してください.
- terminalで次のコマンドを入力してください.
$ source ~/.bashrc最後に
補完機能があれば,typoが減って効率化できます.
- 投稿日:2019-12-14T20:59:13+09:00
はじめての共同開発でGitHubがめっちゃ便利だったって話
はじめに
先月、自分が通っていたCodeBaseというプログラミングスクールの卒業生が参加できる、β版ハッカソンに参加してきました。(β版ハッカソンとはビジネスアイデアはあるけれど技術がない人と技術を学び始めたけれど、まだ実践経験がない人をマッチングしてアプリケーションを開発する場所みたいなものです。)そこで、今まで個人開発でしか使用していなかったGitHubが共同開発で利用するとめちゃくちゃ便利だなと思ったのでここに記しておきます。
GitHubとは
GitHubとはソフトウェア開発においてソースコードをオンライン上で管理できるプラットフォームです。ソースコードをオンラインで管理することにより、エンジニアが協同で開発作業を行なったり、レビューをしてソースコードのブラッシュアップしたりできます。
GitHubが便利だなと思ったポイント
①ブランチを変更することで、アプリを動かせる状態にしつつ開発を行える
アプリケーション開発時には、アプリケーションが常に正常に動いているマスターブランチの他にも、複数のブランチに分岐させることで複数の開発や変更を同時に進めることができます。分岐させたブランチは後でマージすることでそれぞれで開発した機能を1つのブランチに統合することができるので、共同での開発がすごく楽になります。②管理する場所を一元化することで、ファイルの重複を防ぐことができる
自分的にはこれが1番便利だと思ったポイント。パワポとかで例えるとわかりやすいんですけど、パワポの共同作成っていちいちラインにあげたものをダウンロードして、自分の担当のところを編集して、またラインにあげてってしているうちに、同じような名前のパワポが5とか10とか増えていくんです。そうなってしまったらどれが最新かわからないし、どのファイルでどんな変更したかも分からないからいちいちファイルを開くか、変更した人に詳しく聞くかをしないといけなくなります。GitHubではそんなことなくて、プロジェクトが一元管理されているから、変更した部分だけが更新されて、どこを編集したかもわかりやすいのでそういった問題が起こりにくいんです。今回の開発で使いまくったGitコマンド
git branch -a git fetch git checkout branch名 origin branch名 got pull共同開発でメンバーが作ったリモートのリポジトリにアクセスするコマンド群です。これらだけで他人の作ったブランチを簡単に自分のローカルブランチに持ってくることができます。
git add . git commit -m ‘コメント’ git push origin branch名これらは、自分が開発した部分をオンラインに上げることができるコマンドです。変更した部分をすぐにオンラインに共有できたらとても楽ですよね。ちなみに、コメントの部分には自分が開発・変更したことを書くとメンバーにも分かりやすい、効率性のある開発になると思います。
git stash git stash apply stash@{番号}これらは、自分が変更を加えている時に、メンバーの変更部分を統合しないといけなくなった時に一度自分の変更した部分を横に置いておくっていうコマンドです。2行目のapplyコマンドを使用することによりこの横に置いていた部分をまた戻して作業を再開することができます。
共同開発でGitHubを使うときに気をつけるべきポイント
GitHubを使って共同開発をする上で(ていうか共同開発する上で)気をつけようって思ったポイントもありました。
①インデントを揃える
②無駄な改行やスペースを入れない
③いらないコードやコメントアウトは消す
④自分が書いたコードがなぜこのようになったのかというプロセスをissueに書き残す上の3つは個人開発の時によくやってしまっていました。特に③が1番多かった。binding pry や binding irb でシステムの挙動を確認して、また後でやるかもしれないからコメントアウトして置いておくつもりがそのまま忘れてしまうことが多いんですよね。
でも、やっぱり仕事でのシステムやアプリケーション開発って基本的にみんなで一緒に開発していくものだから、誰が見ても見やすい&意味が分かるようなコードの書き方を心がける必要があるなって今回のβ版ハッカソンで強く思いました。
④は何で気をつけるべきかっていうと、自分がなんでこのコードの書き方をしたのかっていうとプロセスを開発メンバーに知っててもらうことで、一緒に開発していくときに生じるズレを少なくしていけるっていうメリットがあります。エンジニアってコミュニケーションのいらない職業って思われがちだけど、システムが動かなくなったり、開発スケジュールの遅延に関わってくることもあるからメンバー同士のコミュニケーションは必須だと思います。
あと、開発の時に詰まったところとその解決策を残しておくことで、後で見返したり、他のメンバーが開発するときの参考になったりするから再現性が高くなるんですよね。
まとめ
というわけで色々書き連ねたんですが、「共同開発でGitHub使おうぜ」って感じでまとめとさてください。ちなみに、自分のつくりたいアプリケーションとかシステムがあったらGitHubで探してみてください。結構いろんな書き方があって参考になると思います。(自分は個人開発の時に色々漁ってました。)
あと、β版ハッカソンめっちゃ楽しかった。まだプログラミングを始めて半年も経たないペーペーの意見にも耳を傾けてくれたし、先輩方の考え方や開発の技術も、参考になってとても刺激になりました。是非ともまた参加したい。
沖縄でエンジニアの勉強始めてみたい方、CodeBaseおすすめなので是非チェックしてみてください。(急な宣伝)
- 投稿日:2019-12-14T19:41:49+09:00
Gitでブロックチェーンのようなことをする
ブロックチェーンはGitと何が違うの?ということでブロックチェーンのようにGitで Proof-of-Work する。
暗号通貨の送金などのトランザクションが
git add
であり、ブロックチェーンのブロックがgit commit
である、として考える。
そうするとブロックチェーンはgitの履歴であり、トランザクションの確定はgit commit
を Proof-of-X することで信頼性(?)が担保される。簡易的な Proof-of-Work を hooks/post-commit に書くことにする。
コミットのハッシュが特定の条件を満たさない場合はコミットのやり直しという感じ。$ git commit --allow-empty -m foo c501d4fd3d6522ac34f0977c87d2942b1438fb1c - f28f9c80a4431fe9f2bd2cc806e1b0880ac58619 - 99513727ca14d70b336a1aaccd11e8c17a65e3c9 - ... ad6e20750dc378eac2a15f73623fb49a0cf45973 - 00a824e2b63a0260e1bec773780d44b323b87b43 - --- done 0s. --- done 7s. [master 3eaaac4] fooなんか最後の出力がミスってるけど、とりあえずこれで。
https://github.com/nishimura/gitmining-hook
$ git log --oneline 0058b75 add readme 0054dde add empty readme 00842e6 update command 009b8bc add post-commit file 0008b42 initial commitコミットハッシュの先頭を
00
に揃えることができた。ランダムな文字列をコミットコメントに追加して PoW している。
コミットコメントやAuthor、Committerを自分の公開鍵のハッシュのみの固定文字にして変更不可にすれば、1秒ごとにマイニングするPoSになる、と思う。コミット時刻が変わるとハッシュが変わるので。ブロックチェーンはトランザクションがブロードキャストされるので、これを更にブロックチェーンに近付けるなら
git add
をブロードキャストするようにしなければいけない。
あとはコミットを検証してコミットハッシュが00
で始まらない場合や間違った計算のコミットはrecieve
もpull
も拒否しなければならない。さて、上記ブロードキャストや検証の仕組みを作っても、今のままでは特に意味は無い。
単に面白いハッシュが作れるという以外の意味を見出すには、コミットに成功したらコインが増えるというような仕組みがないとどうしようもないよね。
普通のGitでいいじゃん、となる。逆に言うと、自分のローカルのリポジトリが見ず知らずの他人によってブロードキャストされたデータで勝手に更新されるような環境だと、PoXが必要なのかもしれない。
ただし、そのデータの価値がコミットのPoXの価値と関連していなければ、やはり普通のGitでいいよね、となる。ブロックチェーンをコイン以外の何かに使うことを考えるというのは、この
0008b42
ハッシュが何かに使えるかと探すようなことかもしれない。
- 投稿日:2019-12-14T18:38:08+09:00
Git fow windows設定備忘録 その1
概要
- Windows10環境で開発をするときのgit for windows導入の仕方。
- リポジトリの同期の仕方。
目的
自分用の備忘録。このため、下記を前提としています。
- Windowsのコマンドプロンプトの操作が多少できること。
- githubのアカウントを持っていること。
- 既に開発中のリポジトリなどがあること。
インストール
Git for Windowsを入手してインストール。
※設定は全部デフォルトのままでOK
設定
git config --global user.name "ユーザー名" git config --global user.email "メールアドレス"Windowsの環境変数に LESSCHARSET = utf-8 を設定。
ローカルにリポジトリを同期
やり方が二つ。cloneか手動で同期。
コマンドラインプロンプトを起動
- チェックアウトしたいディレクトリをエクスプローラーで開く(ex:
c:\test
)- アドレスバーに
cmd
と入れてEntercloneの場合
git clone https://github.com/hoge_user/hogehoge.gitで完了。ただし、
c:\test> git clone hoge
すると、カレントディレクトリの下にリポジトリ名でディレクトリを切るので、c:\test\hoge
が出来てしまいます。
※git clone [URL] [hoge]で任意のディレクトリ名にすることは出来ます。手動で同期させる場合
注意
このやり方は中身が入っているディレクトリでも実施できます。
危険なので中身のバックアップを取ってからでお願いします。ローカルのリポジトリを初期化
git initリモートリポジトリの指定
git remote add origin https://github.com/hogehoge/hoge.git※ここで間違えた場合は
>git remove origin
で。プル & チェックアウト
git pull origin masterこの時点ではupstream指定が無いので、
git branch --set-upstream-to=origin/master master
でupstream(上流)指定しておくか、
push時に-u
オプションで。余談
なんでこんな面倒なことを?
既存の色々入っているアプリのディレクトリに追加の個人設定ファイルだけチェックアウトしたいな、と。
- 投稿日:2019-12-14T14:50:49+09:00
detached HEADになった後にめっちゃcommitしてしまった、、
発生した状況と手順
開発中、同じブランチの以前の状態に戻りたくなり
git reflog
→git checkout <commit id>
で過去の状態に戻った
↓
エラーメッセージっぽいものが出ていたけど、無視してそのまま10回くらいcommitを重ねた
↓
GitHubにPushができなくなってしまったdetached HEADとは
現在の地点が、ブランチから切り離されてしまっている状態。
ターミナルのプロンプトに現在のブランチ名を表示させているのですが、気がつくとブランチ名ではなくd8d36db9f649a163b097
のようなSHA1が表示されちゃってました。何がまずいのか
どのブランチにも属していないので、PUSHができません。
あと、うまいことやらないと行った変更が全て消えてしまいます。うまくいった対処法
新規ブランチを作成し、
$ git branch tmp
元いたブランチに移動し、
$ git checkout create-header
作成したブランチを取り込む
$ git merge tmp
コミット履歴に、マージをした記録が残ってしまいますが、個人的にはオッケーです。
無事解決できてよかった。うまくいかなかった対処法
現在のブランチのSHA1を取得
$ git rev-parse HEAD d8d36db9f649a163b097SHA1からブランチを取得
$ git name-rev d8d36db9f649a163b097 d8d36db9f649a163b097 master現在
master
ブランチが指すコミットにいることがわかったので、移動$ git checkout master
私の場合
git name-rev d8d36db9f649a163b097
をしてもブランチ名が取得できなかったので、この方法ではうまく行きませんでした。
過去のコミットに戻る、という動作をした場合、この方法は使えないのかもしれません。逆にdetached HEADになった直後はこの方法で修正できそうです。
今後に向けて
過去のバージョンに戻りたい時には、
git checkout <commit ID>
ではなくgit reset --hard [commit id]
を使う!参考
gitのHEADがブランチから外れてしまう現象とその直し方
detached HEAD から脱出する方法を git の内部構造から探る
- 投稿日:2019-12-14T13:05:47+09:00
うっかり創業者のコードを上書きしない技術
この記事は SmartHR Advent Calendar 2019 14日目の記事です。
はじめに
私は 3人目あるいは 4人目のエンジニアとして、 2016年2月に SmartHR に入社しました。
あれから約4年、今となっては順調に権限移譲の進んでいる SmartHR ですが、当時は正社員が 7人しかおらず、全社員が様々な仕事を行う小さな企業でした。
当然エンジニアである副社長の @kakipo はプロダクトコードを書いていますし、非エンジニアである @miyasho88 も SmartHR にコードを書いては PR を投げていました。こういった、創業者がコードに込めた思いというのはとても重要であり、おいそれと上書きしてよいものではありません。
この記事では、入社から 4年弱の期間、私がいかにして創業者のコードを上書きしないで済んだのか、その方法をお伝えします。うっかり上書きしないために
さて、では実際にどのようにしてコードの上書きを避けるのか説明します。その答えはいたって簡単で、 Git Hook にスクリプトを仕込むことで解決します。
commit する際に修正箇所の最終編集者を確認、創業者として指定したアカウント名が変更に含まれている場合はエラーを出して commit を中止する、という流れになります。
このスクリプトを実行するためには、創業者が commit に利用したアカウント名がわかる必要がありますので、それはなんとかして手に入れてください。なお、本記事で扱うコードはほぼデフォルトの macOS Catalina 上でのみ動作を確認しておりますので、そのほかの環境では正常に動作しない可能性がありますのでご了承ください。
処理の流れ
スクリプト内で行われる処理の流れとしては以下のようになります。
- git hook の pre-commit でスクリプトが実行されます
- git diff から変更のあった行を取得します
- git blame を使って変更のあった行を誰が書いているのか確認します
- 指定したユーザ名が含まれる行を変更している場合にはメッセージを出力して git commit を中止します
コード
プロダクト直下から
.git/hook/pre-commit
に以下のコードを追記しますBOSS_NAMES=YOUR_BOSS_NAME # カンマ区切りで複数指定可能です file_names=(`git diff --cached --name-only`) for file in ${file_names[@]}; do git_diffs=(`git --no-pager diff --cached --no-ext-diff -U1000000 ${file} | $(cd $(dirname $0) && pwd)/diff-lines.sh | grep -E "^[^\"].*\:[0-9]+\:\-"`) for git_diff in ${git_diffs[@]}; do line=(`echo ${git_diff//:/ }`) origin=`git blame -L${line[1]},+1 HEAD^ ${file} | awk '{print $2}' | sed -e 's/^(\(.*\)/\1/'` if [[ ${BOSS_NAMES} == *${origin}* ]]; then echo "You will overwrite ${origin}'s code in *****:${line[1]}" is_boss_exist=true fi done done if [ "${is_boss_exist}" ]; then echo "Commit aborted." exit 1 fiなお、ここでは簡単のために、 gitで変更ファイルの差分行番号を取得するには? - どこでも見れるメモ帳 で書かれているコードをお借りして行番号を取得しています
そのため、上記のブログで使われている
diff-lines.sh
を.git/hook
ディレクトリに保存し、chmod +x .git/hook
として実行権限を付与する必要があります実際の動作
ちゃんと abort されましたね
どこで誰のコードを消したり上書きしようとしているか一目瞭然です。便利。最後に
今回はうっかり創業者のコードを上書きしないために Git Hook を使ってコミットを中断させました。
しかし、動画作成のためにいろいろと探してみたのですが、 社長のコードはほぼ残っておらず、結果的として 2015年に作られた 12番目の PullRequest をチェックアウトすることとなりました。とても残念です
いつの間にか大量に書き換えていた事実に驚愕です。記憶があれば、来年は おまえは今まで書き換えた創業者のコードをおぼえているのか? をお送りいたします。
明日じゃなくて来年です。みなさま良いお年を!
参考
- 投稿日:2019-12-14T11:16:44+09:00
ローカルリポジトリをGithubにpushする方法
ローカルで作業リポジトリをリモートリポジトリにpushする際の手順。
いつも忘れてしまうので、忘備録として書き留めておきます。// 作業ディレクトリに移動(今回の作業ブランチはstudy-laravelと想定) $ cd workspace/study-laravel // gitを初期化 $ git init // ステージングにあげる $ git add . // コミット $ git commit -m "Initial Commit" // リモートディレクトリを追加 $ git remote add origin <リモートリポジトリのURL> // リモートリポジトリにPush $ git push origin master以上!!
次からはちゃんと覚えます!!
- 投稿日:2019-12-14T03:44:44+09:00
【Docker】error Couldn't find the binary gitが出た時の対処法
error Couldn't find the binary gitが出たDockerfileのソースコード
Nuxt.jsで開発したアプリから、Dockerのイメージを作成した時に「error Couldn't find the binary git」というエラーが起きました。
実際にエラーが起きたDockerfileのソースコードは以下です。
FROM node:10.15.1-alpine as builder WORKDIR /app COPY . /app RUN yarn install --production RUN yarn build FROM node:10.15.1-alpine WORKDIR /app COPY --from=builder /app /app CMD ["yarn", "start"]※Dockerfileの作成方法もまとめているので参考にしてもらえると嬉しいです。
参考:https://qiita.com/arthur_foreign/items/fca369c1d9bde1701e38
Dockerイメージ作成時のエラーログ
エラーログは以下のような感じです。(GCRにイメージをPUSHする想定でした)
$ docker build -t gcr.io/${PROJECT_ID}/app_name:v1 . Sending build context to Docker daemon 157.9MB Step 1/9 : FROM node:10.15.1-alpine as builder ---> xxxxxxxxxx Step 2/9 : WORKDIR /app ---> Running in xxxxxxxxxx Removing intermediate container 0eb38e4dfdc1 ---> xxxxxxxxxx Step 3/9 : COPY . /app ---> xxxxxxxxxx Step 4/9 : RUN yarn install --production ---> Running in xxxxxxxxxx yarn install v1.13.0 [1/4] Resolving packages... [2/4] Fetching packages... error Couldn't find the binary git info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command. The command '/bin/sh -c yarn install --production' returned a non-zero code: 1タイトルや見出しにも書いてる通り、
error Couldn't find the binary git
というエラーが発生していますね。error Couldn't find the binary gitの原因
ちょうど同じエラーがteratailに掲載されていました。
参考:https://teratail.com/questions/179483
teratailのベストアンサーや解決の報告を見るにGitでこけているようですね。
error Couldn't find the binary gitの解決方法
おそらく、teratailはローカルの操作なのでDockerfileにも合わせていきましょう。
Dockerでうまくいかないということは、
alpine
のパッケージマネージャであるapk
にGitを入れる必要があります。そのため、Dockerfileを以下のようにしましょう。
FROM node:10.15.1-alpine as builder WORKDIR /app COPY . /app RUN apk update && \ apk add git RUN yarn install --production RUN yarn build FROM node:10.15.1-alpine WORKDIR /app COPY --from=builder /app /app CMD ["yarn", "start"]すると、Dockerイメージの作成に成功します。
Successfully built xxxxxxxxxxxx Successfully tagged gcr.io/gke_project_name/app_name:v1
- 投稿日:2019-12-14T01:06:42+09:00
コミットメッセージをアスキーアートで装飾する
この記事はHamee Advent Calendar 2019の14日目の記事です。
はじめに
コマンドラインインターフェース(CLI)とアスキーアート(AA)は親和性が高く、
sl
やcowsay
などその親和性を発揮したジョークコマンドが多数存在しているそこで、git-hookを利用して
git commit
したときにコミットメッセージをAAで装飾するジョークhookを作ったぶち当たった壁
某掲示板を中心に発達したAAは主にWindowsのフォントで綺麗に表示されるようにできているため、別の環境でみようとした時に綺麗に見えない可能性がある。(というかフォントが変わると綺麗に見えなくなるのは当たり前だったが実際に見るまで酷さを知らなかった)
元々やろうとしてことはアスキーアートを大量に保存(もしくは外部から取得)しておき、コミットメッセージによってランダムなAAで装飾するものだったが、綺麗に表示されないAAが多かったため断念。
結局自分の環境で綺麗に表示され、できるだけ他のフォントでも崩れないようなAAをいくつか選んで装飾することにした。
装飾例
Roboto Mono Medium for Powerline
サイズ12での表示短いコミットメッセージの場合
タイポを修正 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch test # Changes to be committed: # modified: test長いコミットメッセージの場合
簡潔な説明が書けず長ったらしくなったコミットメッセージの場合 詳細なメッセージが残されている場合もある # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch test # Changes to be committed: # modified: testマージコミットの場合
Merge branch 'test2' into test # Conflicts: # test2 # # It looks like you may be committing a merge. # If this is not correct, please remove the file # .git/MERGE_HEAD # and try again. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch test # All conflicts fixed but you are still merging. # # Changes to be committed: # modified: test2実装
commit-msg#!/bin/sh DOUNIDEMO(){ cat << EOS *'\`\`・* 。 | \`*。 ,。∩∧_,,∧ * + (´・ω・\`) *。+゚ \`*。 ヽ、 つ *゚* \`・+。*・'゚⊃ +゚ ☆ ∪~ 。*゚ \`・+。*・ ゚ EOS } DOG() { cat << EOS \  ̄ヽ、 _ノ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ `'ー '´ ○ O __,.....--‐―― ― ― --..、 ,/ l ヽ \ / / ヽ` l l ! ヽ / ● ● | ! ヽ l ヽノ/ と思うわんわんであった ,! \ │ _ ヽ ,! `´ (::)l | `---、  ̄ l ! `ー 、.._./⌒iノ ! ヽ  ̄ EOS } N_TONE(){ cat << EOS ,-、 ,.-、 ./::::\ /::::::ヽ /:::::::::;ゝ--──-- 、._/:::::::::::| /,.-‐''"´ \::::::::| / ヽ、::::| / ヽ| l l .| ● | んーと l , , , ● l \` 、 (_人__丿 、、、 / \`ー 、__ / /\`'''ー‐‐──‐‐‐┬'''""´ ,-、 ,.-、 ./::::\ /::::::ヽ /:::::::::;ゝ--──-- 、._/:::::::::::| /,.-‐''"´ \::::::::| / ヽ、::::| / ● ヽ| l , , , ● l .| (_人__丿 、、、 | $first_line l l \` 、 / \`ー 、__ / /\`'''ー‐‐──‐‐‐┬'''""´ EOS } max_len=0 first_line='' is_merge=false IFS=$'\n'; for line in `cat "$1"` do # コミットメッセージのうち最も長い行の長さを調べる msg=$(echo $line | awk -F '[#]' '{print $1}'); if [ ${#msg} -gt $max_len ]; then max_len=${#msg}; if [ -z "$first_line" ]; then first_line=$msg; fi fi # マージコミットかどうかを調べる if [ "`echo $line | grep 'Merge'`" ]; then is_merge=true; fi done if [ $max_len -eq 0 ]; then exit 0; fi # マージコミット用のAA if $is_merge; then echo "$( DOUNIDEMO )" >> $1; exit 0; fi # コミットメッセージの横の長さによってAAを変える case $max_len in [1-9]) echo "$( N_TONE )" > $1;; *) echo "$( DOG )" >> $1;; esac
git commit
でメッセージを確定させると末尾にAAが追加され、そのメッセージでcommit
する。学べたこと
ざっくり簡潔に
- 文字列の長さを表示したい時は
${#hensumei}
と書く
while
でパイプを使うと別プロセスで実行され、ループ内部の変数の変化がループ外部で反映されない(ループ外部では値が変化していない)for
を使いパイプなしでファイルを一行ずつ読み込むことでそれを回避できる
- ヒアドキュメント内にカッコが片側だけある場合の出力
test.sh#!/bin/sh echo $(cat << EOS ヒアドキュメントの 例( EOS ) #$ sh test.sh # test.sh: line 3: unexpected EOF while looking for matching `)' # test.sh: line 9: syntax error: unexpected end of file
`" "`
で囲むかfunction
の戻り値から受け取ることでエラーを回避できるtest.sh#!/bin/sh echo "`cat << EOS ヒアドキュメントの 例( EOS `" #$ sh test.sh # ヒアドキュメントの # # 例(test.sh#!/bin/sh MY_FUNC(){ cat << EOS ヒアドキュメントの 例( EOS } echo "$( MY_FUNC )" #$ sh test.sh # ヒアドキュメントの # # 例(おまけ
githubからコミットメッセージを見る
AAのバリエーションがもっと増やせるとよかったなあ と思うわんわんであった