尋常でないもふもふ

a software engineer blog

ghqでGitHubのリポジトリ管理する

概要

ソースコードは Go 言語のエコシステム(?) $GOPATH 配下での一元管理と決められたディレクトリ構造をそのまま活用することにした。そのために便利な ghq を導入する。

GitHub - motemen/ghq: Remote repository management made easy

ちなみにプログラミング言語問わず、ソースコードディレクトリを一元管理するのなら $GOPATH は ~/go よりも ~/dev とか ~/workspace の方が合ってると思うけど、個人的にイマイチしっくりくるワードが思い当たらず、今のところ ~/go 使ってる。

[追記] Go v1.8 の新仕様

$GOPATH が未設定の場合にデフォルトで ~/go をつかうようになるそうだ。

assume GOPATH=$HOME/go if not set

インストール

Homebrew からいれる

$ brew install ghq

設定

$ git config --global ghq.root $GOPATH/src

この設定をしないと ~/.ghq 配下にクローンされる。Go 言語使うなら $GOPATH 直下の src を設定すべき。

リポジトリのクローン

いろいろな書き方ができる

$ ghq get git@github.com:jnst/go-world.git
$ ghq get https://github.com/jnst/go-world.git
$ ghq get jnst/go-world

クローンしたリポジトリへ移動

$ ghq look go-world

pecofzf つかって zsh スクリプトと合わせて使うのが一般的らしいけど、zsh の導入とか各種スクリプトみるとウゲッてなるので自分は ghq look だけでいいや派。

[追記] FishShell + fisherman を導入

ショートカットキー Ctrl + G で超快適なディレクトリ移動を手にいれた。

zshは諦めてたけどfish shell導入したら捗った - jnst blog

プライベートリポジトリをgo getする方法

自分のプライベートリポジトリをgo getすると以下のようなエラーが発生する。

$ go get github.com/jnst/my-private-repo
# cd .; git clone https://github.com/jnst/my-private-repo /Users/jnst/go/src/github.com/jnst/my-private-repo
Cloning into '/Users/jnst/go/src/github.com/jnst/my-private-repo'...
fatal: could not read Username for 'https://github.com': terminal prompts disabled
package github.com/jnst/my-private-repo: exit status 128

原因

普段は GitHubSSH Keys に公開鍵を登録して SSH 認証しているので git@github.com:jnst/my-private-repo.git のような URL を使ってプッシュしたりしてると思うけど、go get の場合は HTTP 経由で行わないとダメらしい。
Personal access tokens を生成して HTTP の URL にくっつけてあげれば OAuth 認証(?)可能になるため、go get も使うことができる。

やり方

https://github.com/settings/tokens

ここから repo 権限にチェックつけて(Organization のリポジトリなら admin:org も必要のはず)トークンを生成してコピーして下記コマンドを実行。

$ git config --global url."https://c61axxxxxxxxxxxxxxx:x-oauth-basic@github.com/".insteadOf "https://github.com/"

c61axxxxxxxxxxxxxxx の部分に生成したトークンを貼っ付ける。
そうすると実行した内容が ~/.gitconfig に追記されて、この状態なら go get github.com/jnst/my-private-repo が可能になっている。

$ go get github.com/jnst/my-private-repo
# cd /Users/jnst/go/src/github.com/jnst/my-private-repo; git show-ref
package github.com/jnst/my-private-repo: exit status 1

参考

Rubyでarray.each_index.injectしたときの括弧は配列展開

こういうやつ

animals = {
  a1: { name: '', type: '哺乳類' },
  a2: { name: '', type: '哺乳類' },
  a3: { name: '蜥蜴', type: '爬虫類' }
}
mammals = animals.reduce([]) do |arr, (id, animal)| # <- ここの丸括弧
  (animal[:type] == '哺乳類') ? (arr << animal) : arr
end

実用例

「プレイヤーID」と「スコア」を持つハッシュがあるとして

player = { id: 1, score: 100 }

あるチームに所属する「プレイヤー毎のスコア」の合計値を独自に算出して「チームのスコア(≒チームの強さ)」を表したい。スコアの計算方法は、Clash of Clan のクランポイント計算と同様に、チーム内で1〜10位は各プレイヤーのスコアの50%、11〜30位は25%といった感じで係数が変わる。
これを Ruby で実装すると配列をイテレートしながら計算するために inject を使うことになるが、プログラムを書く上で配列のインデックスが必要な場合は each_with_index を挟むことになる。

# スコアが高い順にソート
players.sort_by { |player| -player[:score] }
# チーム内で上位にあるほどスコアを高く評価、51位以下は無視
players.each_with_index.inject(0) do |sum, (player, i)|
  sum +=
    case i + 1
    when  1..10 then (score * 0.50).round
    when 11..20 then (score * 0.25).round
    when 21..30 then (score * 0.12).round
    when 31..40 then (score * 0.10).round
    when 41..50 then (score * 0.03).round
    end
end

このとき引数に sum, (player, i) という謎の丸括弧がでてくるが、これは配列を意味する。

players.each_with_index.inject(0) do |sum, arr|
  sum, player = arr

このコードと同じ意味となり、引数内で展開してくれているだけ。

JavaScript でいうところの 分割代入(Destructuring assignment)