コマンドラインからgithubを検索してgit cloneをする with ghs, peco and ghq

![](http://f.st-hatena.com/images/fotolife/s/sona-zip/20141029/20141029212146_original.gif?1414585446)

`ghq`と`peco`を組み合わせてGithubリポジトリを簡単に取得するために、Githubリポジトリをコマンドラインから検索する`ghs`コマンドを作りました。

[sonatard/ghs](https://github.com/sonatard/ghs)

## トライアルページ
[ghs - CodePicnic](https://codepicnic.com/consoles/ghs/embed?sidebar=closed&hide=save,show_result,download,options,run,second_terminal,readme)


## 更新履歴
### 2017/04/15 0.0.10リリース
- 依存ライブラリの`go-github`の下位互換性がなくなったため、ビルドできなくなっていたバグを修正しました

### 2016/05/14 0.0.9リリース
- `-k`, `--fork`オプションを追加しました 検索結果にforkしたリポジトリを含める(true)、含めない(false),forkしたリポジトリだけ表示(only)を指定することができます。
- 検索結果が0件だった場合にghsが終了しないバグを修正しました


### 2016/05/03 0.0.8リリース
- `0.0.7`で発生していた`-m`,`--max`オプションにて100件より大きい値を指定した場合に正しい件数の結果が表示されないバグを修正しました
- 並行処理を追加して以降バグが多いのでテストを追加しました

### 2015/12/30 0.0.7リリース
- `0.0.6`で発生していた`-m`,`--max`オプションにて100件より大きい値を指定した場合のバグを修正しました

### 2015/12/30 0.0.6リリース
- `-m`,`--max`オプションで100より大きい値を指定した場合の高速化を実施しました(が、1000件以上表示される、同じ結果が表示されるなどのバグがあるので近いうちに0.0.7をリリース予定です)
- `-t`,`--token`オプションを追加しました　Github API Tokenを指定することにより、Github API rate limitの上限を増やすことができるようになりました。Tokenの指定は`-t`オプションだけではなく`GITHUB_TOKEN`環境変数や`gitconfig`の内の`github.token`などからも指定可能です。詳細は下記の説明をご確認ください。
- `-f`,`--fields`オプションを追加しました　今までは検索対象を絞る際には、検索クエリに`in:name`のように追加することで可能でしたが、`-f name`で指定可能になりました。

### 2015/10/21 0.0.5リリース
- デフォルトの検索結果の表示件数を最大100件に変更しました
- 検索結果の最大を指定する`-m`,`--max`オプションを追加しました 1-1000を指定可能。
だたし現在1000を指定すると、リクエストを10回シーケンシャルに処理するためとても遅くなります。
近いうちに次のバージョンでリクエストの並行処理を実施して高速化する予定です。
 
### 2015/6/5 0.0.4リリース
- 検索対象をGithub Enterpriseに変更する -e, --enterpriseオプションを追加。
- go-latestに対応。 -hや-vを実行するとバージョンチェックを行い最新版がリリースされている場合にはメッセージを表示します。
- homebrew, linuxbrewからのインストールに対応。

### 2015/3/3 0.0.3リリース
- リポジトリ名が40文字を超えると紹介文と重なってしまう不具合の修正。
- -u,-rオプション指定時は引数なしでも実行できるよう変更。


## 機能紹介
`ghs`コマンドはとてもシンプルで、引数として検索クエリを与えるとGithubリポジトリから検索してリポジトリ名とリポジトリの紹介文を出力します。

```zsh
[sona ~]$ ghs github
michael/github                          A higher-level wrapper around the Github API. Intended for the browser.
peter-murach/github                     Ruby interface to github API v3
jwiegley/github                         The github API for Haskell
isaacs/github                           Just a place to track issues and feature requests that I have for github
gulinghao1847/github
chscodecamp/github                      GitHub Seminar
opauth/github                           GitHub authentication strategy for Opauth
Kdyby/Github                            Github API client with authorization for Nette Framework
```

引数として与えるクエリの詳細は`ghs`のヘルプと公式ドキュメント[Search | GitHub API](https://developer.github.com/v3/search/)と[Searching repositories](https://help.github.com/articles/searching-repositories/)を参照してください。
Webブラウザ上のリポジトリ検索と同等のクエリを指定可能なため`user:`や`language:`による絞り込みも可能です。

```zsh
[sona ~]$ ghs "language:go user:sonatard ghs"
sonatard/ghs                            'ghs' is a command-line utility for searching Github repository .
```


## ghs options

```zsh
[sona ~]$ ghs --help
Usage:
  ghs [OPTION] "QUERY"

Application Options:
  -f, --fields=     limits what fields are searched. 'name', 'description', or 'readme'.
  -k, --fork=       Forked repositories icluded in results. 'true', 'only' or 'false'.
  -s, --sort=       The sort field. 'stars', 'forks', or 'updated'. (default: best match)
  -o, --order=      The sort order. 'asc' or 'desc'. (default: desc)
  -l, --language=   searches repositories based on the language they’re written in.
  -u, --user=       limits searches to a specific user name.
  -r, --repo=       limits searches to a specific repository.
  -m, --max=        limits number of result. range 1-1000 (default: 100)
  -v, --version     print version infomation and exit.
  -e, --enterprise= search from github enterprise.
  -t, --token=      Github API token to avoid Github API rate
  -h, --help=       Show this help message

Github search APIv3 QUERY infomation:
  https://developer.github.com/v3/search/
  https://help.github.com/articles/searching-repositories/

Version:
  ghs 0.0.9 (https://github.com/sonatard/ghs.git)
```


## インストール
[homebrew](http://brew.sh/index_ja.html), [linuxbrew](http://brew.sh/linuxbrew/)からインストール可能です。

```zsh
brew install sonatard/tools/ghs
```
Windowsは以下からダウンロードをお願いします。
[Releases · sonatard/ghs](https://github.com/sonatard/ghs/releases)

## 背景
最近motemen氏作成の[ghqコマンド](https://github.com/motemen/ghq)により大変リポジトリの管理が楽になり快適な開発生活を送っています。

そんな日々の中で「あのリポジトリ欲しいな」と思うことが多いのですが、ツール名からリポジトリ名を一意に引けないため1度Webブラウザからツール名でGithubリポジトリを検索して`username/reponame`の組み合わせを調べた後に、以下のようにリポジトリをcloneしていました。

```zsh
ghq get username/reponame
```

このWebブラウザで検索するという作業さえ解消できればコマンドで完結できるのではないか？という思いから、コマンドでGithubリポジトリを検索する`ghs`コマンドを作成しました。

## 使い方

標準的な使い方です。
サーチ対象はリポジトリ名、Readme、紹介文になります。

 ```zsh
 ghs "dotfiles"
 ```

`-f`,`--fields`オプションをを使うことによりサーチ対象を絞ることができます。

 ```zsh
 ghs -f name "dotfiles"
 ```

また`-u`,`--user`オプションでユーザを指定可能です。

 ```zsh
 ghs -f name -u sonatard "dotfiles"
 sonatard/dotfiles                       dotfiles
 ```

## Github API Rate limitの制限にかかる場合の対応

Tokenの値は以下の優先順位で利用されます。

- 1.`ghs`実行時の `-t` or `--token`オプション

```bash
$ ghs -t "....."
```

- 2. `GITHUB_TOKEN` 環境変数

```bash
$ export GITHUB_TOKEN="....."
```

- 3. `gitconfig`内の`github.token`

```bash
$ git config --global github.token "....."
```

## 本題　ghsとpecoとghqと組み合わせてGithubリポジトリを取得する

ここからが本題のコマンドのみでGithubリポジトリを取得する手順になります。

pecoとghqの導入はこちら。
[Releases · peco/peco](https://github.com/peco/peco/releases)
[Releases · motemen/ghq](https://github.com/motemen/ghq/releases)

```zsh
ghs クエリ | peco | awk '{print $1}' | ghq import
```

見たとおりですが流れとしては以下のようになります。
1. `ghs`によりGithubリポジトリを検索
2. `peco`によるフィルタリング
3. `awk`でリポジトリ名を取得
4. `ghq　import`によるリポジトリのclone

`peco`でフィルタリングする際は`Ctrl + Space`で複数選択すると同時に複数のリポジトリをcloneすることが可能です。

## zsh関数

先ほどのコマンドをzshの関数として登録しておくとより便利に使うことができます。

```zsh
function gpi () {
  [ "$#" -eq 0 ] && echo "Usage : gpi QUERY" && return 1
  ghs "$@" | peco | awk '{print $1}' | ghq import
}
```


## Demo

![](http://f.st-hatena.com/images/fotolife/s/sona-zip/20141029/20141029210952_original.gif?1414584687)

1. `gpi クエリ`で実行
2. `peco`でフィルタリング
3. `ghq`でclone


## おまけ

`gpi`のcloneとは反対にローカルリポジトリを削除する`gpr`コマンドも定義すると便利です。

```zsh
function gpr () {
  ghq list --full-path | peco | xargs rm -r
}
```

## まとめ
`ghs`と`peco`と`ghq import`を組み合わせた`gpi`により容易にリポジトリを取得することが可能となりました。
検索と組み合わせられているので曖昧な記憶をたよりにリポジトリを取得できるところが大変便利です。


初めてGo言語でスクラッチ開発したものなので、容赦ないPRお待ちしています！