shields.io経由でだいたいなんでも自由にバッジ表示する

# バッジ on README.md

OSSをGitHub等で公開するにあたっては、様々な情報をバッジとしてREADME.mdに貼っておくことがよくあると思います。

[クラウドサービスを活用して README にバッジをペタペタ貼る - Qiita](https://qiita.com/dtan4/items/13b0ea9edf5b99926446)
> ![badges][badges]

（画像引用）

[badges]: https://camo.qiitausercontent.com/94851dbe15f3429eb357c34b2f7e753acbb7399b/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f31373530382f34613537366236342d326436652d663930382d336565392d6437633661373162376564662e706e67

私もバッジは貼りたい派です。

- シャレている
- テスト、ビルド結果を表示しておくというのが恐らく最も主要な目的であり（要出典）、必然的に：
    - テストの存在、
    - （テストを整備、維持しようとする気持ち、）
    - 自動テストand/orビルド環境の存在、などを前提とする
- README.mdを小綺麗に整えようという姿勢を示せる
- カラフルでシャレている

正直、目的意識についてはあえてあまり深く考えない方がいいしてきた。

とりあえず貼っていこう。

# 動的な情報をバッジとして表示する

masterのテスト結果やcode climateなどは、その情報を握っているwebサービス自体がSVG等の画像を動的生成するAPIを持っていることが多く、そのURLを画像のソースURLとして直接指定することで簡単にバッジとして表示できます。

また、ユーザ指定の静的な情報をバッジとして表示するのも、[shields.io](https://shields.io/)を使うことで簡単にできます。

```
https://img.shields.io/badge/<SUBJECT>-<STATUS>-<COLOR>.svg
```

このような形式のURLを用意するだけ。

```
https://img.shields.io/badge/sample-good-green.svg
```

こう書けば、

[![sample](https://qiita-image-store.s3.amazonaws.com/0/76980/f677988c-839d-cf15-3737-d520b5cddc31.png)][samplesvg]

[samplesvg]: https://img.shields.io/badge/sample-good-green.svg

こうなります。日本語もいけるようです。

では、webサービスに関連付いたものでもない（shields.ioにもバッジが用意されていない）が、かといって静的なものでもなく、どこかに保存されていて動的に変化しうる情報をもとにバッジを表示したい場合はどうするのがいいでしょうか。

**実はこれもshields.ioでできます。**条件は、

- 元情報がJSONで取れて、
- 認証が不要であること。

たとえば、[Elm](http://elm-lang.org)のpackageは http://package.elm-lang.org に集約されていますが、shields.ioにはまだelm-package versionバッジは用意されていません。RubyGemsやnpmのようにそのうち対応するのを待ってもいいですし、ない間は手書きで書いておくという手もありますが、そこはやっぱり自動生成させましょう。

shields.ioにはdynamic badgeという機能があります。以下のようにURLを構成して画像ソースに指定するだけ。

```
/badge/dynamic/<TYPE>.svg?uri=<URI>&label=<LABEL>&query=<$.DATA.SUBDATA>&colorB=<COLOR>&prefix=<PREFIX>&suffix=<SUFFIX>
```

|slot|value|
|----|-----|
|`TYPE`|今のところ`json`だけの模様|
|`URI`|情報取得元のURL。URL encodeしましょう。認証不要で、JSONを返すならなんでもOKのはず|
|`LABEL`|バッジの左半分に表示するラベル|
|`$.DATA.SUBDATA`|取得したJSONのどこのフィールドの値をバッジの右半分に表示するか。[JSONPath][jp]クエリで指定|
|`COLOR`|バッジ右半分のHex color|
|`PREFIX`|クエリで取得した文字列につける接頭辞|
|`SUFFIX`|同じく接尾辞|

[jp]: https://www.npmjs.com/package/jsonpath

Elm packageの最新バージョンは、GitHubレポジトリのmasterにある、`elm-package.json`というファイルの`version`フィールドの値を正とすればいいでしょう。raw.githubusercontent.comから取ってこれますね。

- （GitHubにはpushしてあるが`elm-package publish`はしていない、という状態もあり得ますが、気にしません）
- （ちなみに、Elm 0.19以降は`elm.json`となります）

[elc]: https://github.com/elm-lang/core/tree/master

組み合わせて、

```
https://img.shields.io/badge/dynamic/json.svg?label=elm-package&colorB=5f9ea0&query=$.version&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fymtszw%2Felm-xml-decode%2Fmaster%2Felm-package.json&prefix=v
```

このURLにより、

[![elm-package](https://qiita-image-store.s3.amazonaws.com/0/76980/eacde27d-02cb-e86e-f78b-2551b3a4f1cb.png)][epsvg]

[epsvg]: https://img.shields.io/badge/dynamic/json.svg?label=elm-package&colorB=5f9ea0&query=$.version&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fymtszw%2Felm-xml-decode%2Fmaster%2Felm-package.json&prefix=v

このように生成できました。

# おわり

書いといてなんですが、badgeは表示先サービス（ここではGitHub,それにQiita）の画像cacheとの兼ね合いで、表示されないことが時々あります。[^1]
そこへ来て元情報まで外部リソースに依存するdynamic badgeともなると、さらに失敗する確率は上がります。
shields.ioのサーバが反応しないケースもありえます（rate limitか過負荷なのかは不明）。

実はこの記事の例もタイミングによって表示されてないケースが結構あったので、**こっそりPNGに逃げています！** あしからず。
static badgeの方が多少はマシだと思うので、バージョン番号表示くらいならstaticにしてversion upのたびに書き直しが無難かも。

適切に使い分けつつ、なんでもバッジ表示してシャレオツにしていきましょう。

[^1]: shields.io側に`?maxAge=3600`などのオプションもあるので、ある程度コントロールできそうです。