Travis CI で Linux (x86_64, i686, aarch64) 向け(とついでに macOS 向け)に Rust で書いたツールのバイナリをリリースする
git-brws のリリース で微妙に Travis CI 上の rust 環境でハマったのでメモ.
前提として,cargo build
でビルドできるものとします.Travis の環境はツールチェーンが古いと困るので Ubuntu 14.04 を使ってます.今回は下記の環境向けのバイナリをビルドしてリリースしました.
Linux は musl libc を使う選択肢もありますが,使い慣れた glibc にしました.
3行で
ビルド環境
まずは matrix:
でビルドを回すジョブを書いておきます.これによって,1回の CI で4つのビルドが走ります.
matrix: include: - os: osx rust: stable env: TARGET=x86_64-apple-darwin - os: linux rust: stable env: TARGET=x86_64-unknown-linux-gnu - os: linux rust: stable env: TARGET=i686-unknown-linux-gnu - os: linux rust: stable env: TARGET=aarch64-unknown-linux-gnu
cargo
でビルドするときにターゲットを指定する必要があるので $TARGET
変数に triple を指定しておきます.未指定だとデフォルトのターゲットが使われるので実質必要なのはクロスコンパイルが必要な i686-unknown-linux-gnu だけですが,Travis のビルド一覧で分かりやすいので書いておきます.
os:
は osx
だと macOS が,linux
だと Ubuntu 14.04 が使われます.
Deploy 設定を書く
deploy: provider: releases api_key: secure: XXXXX file: git-brws-${TRAVIS_TAG}-${TARGET}.zip skip_cleanup: true on: repo: rhysd/git-brws # On specific condition -> condition: $TRAVIS_RUST_VERSION = nightly # # Only deploy tagged commit tags: true
初期設定は travis
コマンドがやってくれるので,gem install travis
して travis setup releases
するいつものやつで生成し,そのあと自分用の設定を足します.
今回はビルド後の before_deploy
で zip に固めているので,生成物を削除されないように skip_cleanup
を付けています.また,タグを打ったときだけリリースしてほしいので,tags: true
を指定してます.
ここまでが Travis の一般的なリリース設定です.
rustup を自前で入れる
Travis の rust ツールチェーンの管理は,rustup がまだシェルスクリプトで書かれていた頃のものを使っているようなので,最新の rustup
コマンドを入れます.
before_script: - sh ~/rust/lib/rustlib/uninstall.sh - export PATH="$PATH:$HOME/.cargo/bin" - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION - rustc -V - cargo -V
$TRAVIS_RUST_VERSION
でインストールされるツールチェーンのバージョンを指定しているので,新しい rustup
でも同じバージョンの Rust がインストールされます.
ここは Travis の環境が更新されればいずれ要らなくなるかもしれません.
ターゲットの追加
i686 向けのビルドにはクロスコンパイルする必要があるので,i686 向けのツールチェーンを入れます.
before_script: - if [[ "${TARGET}" == "i686-unknown-linux-gnu" ]]; then rustup target add $TARGET; fi
また,aarch64 向けの gcc はコマンド名が aarch64-linux-gnu-gcc
なので,cargo
がリンク時にそっちを使うようにします..cargo/config
に TOML 形式でビルド設定を書けます.
before_script: - | if [[ "${TARGET}" == "aarch64-unknown-linux-gnu" ]]; then rustup target add $TARGET aarch64-linux-gnu-gcc -v mkdir -p .cargo echo "[target.${TARGET}]" > .cargo/config echo "linker = \"aarch64-linux-gnu-gcc\"" >> .cargo/config cat .cargo/config fi
また,今回は glibc を使ってビルドするので,リンクに 32bit 環境の gcc を入れます.これには apt addon を使って gcc-4.8-multilib パッケージをインストールしておけば OK です.gcc-multilib は gcc 4.4 でかなり古いので gcc-4.8-multilib にしました.
addons: apt: packages: - gcc-4.8-multilib - gcc-4.8-aarch64-linux-gnu - gcc-aarch64-linux-gnu - libc6-arm64-cross - libc6-dev-arm64-cross
ビルドして zip に固める
ここは普段通りリリースビルドして成果物を入れるディレクトリをつくり,zip に固めるだけです.各環境向けに $TARGET
を指定してやります.
before_deploy: - cargo build --target $TARGET --release - mkdir "git-brws-${TRAVIS_TAG}-${TARGET}" - cp target/$TARGET/release/git-brws LICENSE.txt README.md "git-brws-${TRAVIS_TAG}-${TARGET}" - zip "git-brws-${TRAVIS_TAG}-${TARGET}.zip" -r "git-brws-${TRAVIS_TAG}-${TARGET}"
これで tag 付きのコミットが push されるとクロスビルドに必要なツールが入り,ビルドされ,成果物が zip で GitHub のリリースページにアップロードされるはずです.
また,上記の設定で macOS でもビルド及びリリースできているはずです.
今手元に Windows マシンが無いのでできませんが,AppVeyor でのビルドも try してみる予定です.
2016 年につくったやつ一覧
GitHub contributions グラフを続けるのも4年目に入っていて,来年も無理しない程度に続けて行こうかなぁと思ってます.今年は中盤あたりイマイチだったけど後半結構時間ができたので例年通りぐらいになりました.
今年もぼちぼち使っているツールのためのプラグインとか,ほしいアプリとかで新しく色々つくった気がするのでまとめてみました.
- crdoc: Crystal のドキュメントをコマンドラインから引けるコマンドラインツール
- ask-on-exception: 例外が出た時に自動的に例外のメッセージで StackOverflow を検索してくれるネタモジュール
- devdocs.vim: devdocs.io を Vim から直接引ける Vim プラグイン
- vim-wasm: WebAssembly のテキスト形式 wasm の Vim ファイルタイププラグイン
- subvim: Vim 内から別の gVim を立ち上げ,セカンドスクリーンとして使える Vim プラグイン.最近自宅でもモニター増えたので便利にしていきたい.
- dot-github: GitHub の issue/PR テンプレート を簡単につくれるコマンドラインツール.
- unite-redpen.vim: redpen を unite.vim のインターフェースで使える Vim プラグイン.
- tinyjson: Rust 勉強用につくった JSON パーサ.Rust を書くのが目的だったので依存関係なしで安定板で動くようにした.
- tmux-edit: Tmux で選択中のパスを直接エディタで開ける tmux プラグイン.
- abspath: 相対パスと絶対パスが混ざらないようにするために絶対パスのみを表す型を提供する Go ライブラリ.
- npm-filetypes.vim: npm-debug.log や .npmrc などの npm 関連のファイルのファイルタイプ Vim プラグイン.
- dotfiles: dotfiles のシンボリックリンクを張ってくれるコマンドラインツール.何気に活躍してる.
- wdio-appium-service: Appium を webdriver.io の
wdio
コマンドと一緒に使うための service プラグイン. - 8cc.vim: ELVM でつくった Vim script 製 C11 コンパイラ.
- rehype-react: HTML の構文木 HAST を React の仮想 DOM に変換するためのライブラリ.
- ChromeDeck: モバイルブラウザが TweetDeck みたいにマルチカラムになれば便利じゃないかというアイデアでつくったプロトタイプ.あんまり便利じゃなかった.
- electron-open-url: Mac の
open
や Linux のxdg-open
のように URL を開くコマンドラインツール.ただしブラウザとは別に Electron で開く. - translate-markdown: Markdown テキストを Google 翻訳に投げるコマンドラインツール.
- remark-emoji: Markdown の構文木処理ライブラリ remark で絵文字記法を扱うための remark プラグイン.
- bytesize-icon-elements: svg なアイコンセット bytesize-icons を Custom Elements として使えるようにするラッパー.
- electron-in-page-search: Electron のページ内検索をクロスプラットフォームかつ
BrowserWindwo
と<webview>
の両方で簡単に使えるようにするためのライブラリ. - unite-oldfiles.vim: Vim で最近使ったファイルを開ける unite.vim プラグイン.Vim の oldfiles 機能を利用.
- react-component-bytesize-icons: bytesize-icons を React コンポーネントとして使えるようにしたライブラリ.線の太さやサイズを指定すると良い感じにしてくれる.TypeScript コードを生成するスクリプトを書いてテストも書いた.
- eslint-config-fixable-all: eslint のルールのうち
--fix
で直せるルールを違反しているとエラーになるようにできる eslint プラグイン.簡単に本家に追従できるように生成スクリプト一発で更新できるようになってる. - heredocument: JavaScript でも Ruby の
<<~
のようなヒアドキュメントが書きたい時用のライブラリ.ES6 のテンプレート文字列のタグでヒアドキュメント文字列が書ける. - vim-gfm-syntax: GitHub Flavored Markdown の色々なもの(絵文字とかコードとかテーブル記法とかタスク記法とか)をハイライトするためのプラグイン.絵文字記法を本来の絵文字で置き換える絵文字 concealing も追加した.
- Chromenu: メニューバーやホットキーで素早くアクセスできるモバイルブラウザ.
- vim-color-spring-night: スクラッチからつくった Vim のカラースキーム.
- git-brws: 今いるリポジトリのページやコミット,diff, ファイルなどをブラウザ内で開くためのコマンドラインツール.GitHub, bitbucket, GH:E, Gitlab に対応してる.Rust 製.
また,GitHub 検索 によると,今年は 130 件の pull request を出したようです.(自身のリポジトリ除く,public リポジトリのみ)
あと去年からつくっているもののメンテや継続的な開発も引き続きやっていて,NyaoVim には結構時間を割いたと思います.
前半にソフトウェアデザインに記事を寄稿したり,システムプログラミング会で発表させてもらったりしました.
来年もぼちぼち頑張っていきたいと思います.良いお年を.
フルスクラッチからさいきょうの Vim カラースキームをつくろう!
この記事はVim Advent Calendar 2016 その2の18日目の記事です.その1のほうにも記事を書いたのですが,こっちもまだ空いてたので埋めがてら書きます. その1のほうではかなり非実用的な記事を書いてしまったので,こっちでは比較的実用的なことを書きます.
'穏やかな'カラースキーム spring-night
突然ですが,ここ数日で sprint-night という新しいカラースキームをつくりました.
- MacVim で Vim script のコードを開いた時
- 半透明ターミナル + Vim で Go のコードを開いた時 (24bit 色)
紺色の背景に黄色系の文字色をメインにしたコントラスト少なめのカラースキームです. 一番特徴的なのはビジュアルモードでピンクを採用している点です(桜をイメージしています).黒背景なので 'night' です.
今までスプラトゥーン感のあるカラースキームや,いくつか試しにつくってみたカラースキームもありましたが,実用には至りませんでした. ですが今回は結構満足いく感じにできて,実際に今も使って記事を書いています.
今回はどうやって,どう考えてこのカラースキームをつくったかを紹介します.
カラースキームがほしくなったら…
まずカラースキームがほしいときは,本当に自作すべきか考えるところから始まります. 優先順位的には次のような感じです.
- 要求に合うカラースキームが無いか試しまくる
- 要求に一番近いカラースキームを fork して不満点を修正する
- つくる
まず 1. についてはカレンダー12日目の記事のように,調査していただいている方の記事がいくつかありますので,片っ端から試してみると良いと思います.
Vim の割と新しいおすすめ colorscheme たちを紹介する - Qiita
試す時はわざわざインストールすると面倒なので,手前味噌ですが,try-colorscheme.vim を使うとインストールせずにインメモリで Vim にカラースキームを適用できます.
ジャストフィットするものがあればそれで確定ですね.無くても,いくらか修正すれば満足行くものができるのであれば fork して直接修正してしまうのが良いです. 僕は wombat256 を fork したものをずっと使い続けていました.wombat はとても良いカラースキームなのですが,一部対応していないハイライトがあったり少し気に食わないハイライトがあったりした箇所を修正して使っていました.
使いたいものが全然無い場合,もしくは作りたいコンセプトのカラースキームがある場合はようやく 3. のつくるフェーズに入ります. 僕は前述の fork も気に入っているのですが,Vim8 で端末でも RGB の24bit色(true color)が使えるようになったこともあり,24bitカラーをフルに使ったもので自分好みのものがほしくなりました.
コンセプトを決める
まず最初にやるのはカラースキームのコンセプト決めです.
カラースキームをつくっていると,どうしても今いじっているところの色合いだけが気になってしまって全体として統一感がなくなってしまいます. それを防ぐために,迷った時などに決定を助けるコンセプトを持っておくのが良いです.
seoul256 を見てローコントラストなカラースキームが良いなと思っていたので,紺色背景 + 薄い黄色で春っぽいローコントラストなカラースキームをつくろうとなりました. なぜ紺色 + 黄色なのかは後述します.
コンセプトは明確なほど良く,一番良い例としてはバットマンのゴッサム・シティをコンセプトにした vim-gotham があります.これぐらい強いコンセプトがあるとまず迷うことは無さそうです.
ブラウザで色合いを考えて最初のカラースキームを '生成' する
スクラッチからといっても手で書く必要はありません.
ブラウザ上でインタラクティブに色をカラーピッカーで選びながらカラースキームがつくれるサービスがいくつかあります. 僕は Theme Creator というサービスを使って最初のプロトタイプを生成しました. Theme Creator では12箇所のハイライトをプレビューを見ながら決めます. 画像から色を抽出してみたり,Platton のような配色サービスを使ってみても良いと思います.
配色については,iceberg をつくられた cocopon さんの記事が参考になりました.
また,コントラストが低いカラースキームでも見えにくくならないように,補色関係にある紺色と黄色をメインにすることにしました.
とりあえず気になった配色を手当たり次第に試してみます. こんな感じのがほしいなというのができあがったら,それをコードとして生成します.
カラースキーム開発環境を整える (ライブリロード)
生成されたコードをブラッシュアップしていく前にカラースキームの開発環境を簡単に整えておきます. 今回は 24bit 色および(おまけで)8bit 色にも対応するので,下記の3つの環境で色合いを見る必要があります.
毎回カラースキームを編集するたびに読み込み直すのは手間です.また,少なくとも自分がよく使う言語3つぐらいの色合いは確認しながら進めたいところです.
ウェブの開発にはライブリロードというものがあります.手元で編集したコードがブラウザに即時反映されるものです.カラースキーム開発でもこういうことがやれると楽になりそうです.
そこで,下記のような設定を .vimrc に(カラースキーム開発中だけでも)足します.
function! s:auto_update_colorscheme(...) abort if &ft !=# 'vim' echoerr 'Execute this command in colorscheme file buffer' endif setlocal autoread noswapfile let interval = a:0 > 0 ? a:1 : 3000 let timer = timer_start(interval, {-> execute('checktime')}, {'repeat' : -1}) autocmd! BufReadPost <buffer> source % endfunction command! -nargs=? AutoUpdateColorscheme call <SID>auto_update_colorscheme(<f-args>)
:AutoUpdateColorscheme
というコマンドを定義しています.
Vim には編集中のバッファが外部で変更された時に自動でリロードする autoread
というオプションがあるので,それを有効にします.
それだけだと autoread
はすぐに変更を検知してくれないので,:checktime
とタイマーを使って3秒ごとにポーリングします.
これで作業用の Vim で編集するとプレビュー用の Vim が変更を検知し,バッファを更新,BufReadPost
イベントが発火してカラースキームをリロードします.
タイマーとラムダ式と execute()
を使っているので Vim8 専用です.
gVim と端末 Vim (8bit色環境) と端末 Vim (24bit色環境) を立ち上げ,ウィンドウを4分割ぐらいして自分のよく使う言語のコードを3つのウィンドウで開き,最後のウィンドウで編集予定のカラースキームファイルを開きます.
最後に :AutoUpdateColorscheme
と打っておけば準備完了です.
生成されたコードを整える
それでは生成されたコードを整えていきます.
今回僕が使った Theme Creator ではこういう感じのコードが生成されていました.
" ハイライトの色の定義 let s:bg="#334152" let s:fg="#FFFEEE" let s:fg2="#ebeadb" let s:fg3="#d6d5c8" " ... " 各ハイライト要素へのハイライトの適用 exe 'hi Normal guifg='s:fg' guibg='s:bg exe 'hi Cursor guifg='s:bg' guibg='s:fg exe 'hi Cursorline guibg='s:bg2 exe 'hi CursorColumn guibg='s:bg2 " ...
前述の cocopon さんの記事にも書かれていましたが,カラーパレットを作成して自分が使っている色数が分かるようにするのは良い習慣だと思います. ここでは前半の変数定義がそれに当たります.ただ,同じ色を複数箇所で使いまわしたりするので,現在の変数名はあまり良くありません. 各色ごとの名前に変えておきます.
let s:green = ['#a9dd9d', 150] let s:gold = ['#fedf81', 222] let s:darkgold = ['#685800', 58] let s:red = ['#fd8489', 210] let s:mildred = ['#ab6560', 167] let s:mikan = ['#fb8965', 209] " ...
今回は 8bit 色にも対応したので,配列にして第2引数に 8bit 色を指定しました.24bit 色のみで良い場合は右辺はそのままでも良いと思います.
ちなみに 24bit 色 → 8bit 色の変換は CSApprox というプラグインで変換してから微調整するのが良いです.
256色パレットは一番暗い辺りの色合いが(灰色系を除いて) 00
からいきなり 5f
に飛ぶので色々妥協します(飽くまでメインは 24bit 色です.)
また,後半については 24bit 色のみ対応であればそのままでも良いですが,8bit にも対応するので s:hi
という関数をつくり,引数で色を表す配列と bold などの属性を渡せるようにしました.このあたりはソースコードを見ていただいたほうが良いかもしれません.
カラースキームの基本的なことは :help hi
を見たり,他のカラースキームの実装を見たり,thinca さんの解説記事 があるので割愛します.前章で用意したライブリロード環境を使って実際に値を変えてみるとよく分かると思います.
足りないハイライト要素を足す
Vim の基本的なハイライト名は :help highlight-groups
に各ハイライトが実際にどこで使われているかの説明付きで載っているので,手元のコードにまだないハイライトを足します.
配色はあまり考えすぎず,まずは網羅的にハイライトを定義することを優先します.
ハイライトを調節する
それではいよいよ一番大変で楽しいところです.
色合いをひたすら調整していきます.このあたりはもっと良い方法があれば良いのですが,特にそういう方法は知らなかったのでひたすら RGB 値を調節していきます.この時考えたことについて2点紹介します.
1. ハイライトをグルーピングする
すべてのハイライトに別の色を割り当ててしまうとカラフルになりすぎるので,ハイライトのグループに分けます.今回は大まかにプログラムの要素ごとに色を分けてみました.
例えば制御構文であれば if
や switch
といった条件分岐と for
や while
などのループを含みます.
また,定数値はマジックナンバーとして目立たせるために強めの色を使います.特に論理値は真偽を間違えやすいので気をつけて配色します.今回は赤を採用しました.文字列を別にしているのは,文字列は数値などに比べ範囲が広いので強い色を使うと目がつらいためです.
このように,プログラムの各要素ごとに色を分けることで,離れてみた時やぱっと見た時にプログラムの構造をつかみやすくなるのではないかと考えてます.
2. コントラストを変えられるようにする
Tomorrow-Night や一部の有名カラースキームではコントラストを調整できるものが結構あります.
これはカラースキームの色合いがウィンドウの半透明・不透明やディスプレイの明るさなどにも影響されるからだと思います.実際,最初は不透明ウィンドウのみを見て配色していたのですが,後から半透明ウィンドウで見るとコメントが見づらすぎて調整し直したということがありました.
CI する
とりあえずこんなもんか というところまできたら,カラースキームも CI すべきだと思います. 単体テストを書くまではいきませんが,下記の観点でチェックしておくと良いと思います.
- ハイライトが重複していないかチェック
- Vim がハイライトを読み込んでエラーを出さないかチェック
- linter によるスタイルチェック
1つめはハイライトを足したり引いたりしているとついついやってしまうミスです. また,2つめは最低限エラーが出ないことを smoke test 的にチェックしています. もっと色々なチェックを足すこともできると思いますが,費用対効果的にこんなものだと思います.
テストは Travis CI を使っていて,設定は下記のようになりました.linter は vint を使っています.
language: python install: - pip install vim-vint before_script: - uname -a - vim --version script: - vint --warning $(git ls-files | grep -e '\.vim$' | grep -v vital) --color - vim -E -c 'set t_Co=256 rtp+=.' -c 'try | colorscheme spring-night | catch | cquit | endtry' -c 'quit' - ruby .ci/check_duplicate.rb
.ci/check_duplicate.rb
はカラースキームのファイルを雑にパースしてハイライト名が重複していないかチェックするスクリプトです.
script:
の2行目で実行している vim
コマンドは,カラースキームを読み込んで問題なければ 0
で exit し,エラーが出れば 1
で exit するワンライナーです.
ブラッシュアップする
ここまできたら実戦投入します.自分のデフォルトのカラースキームを作成したものにし,日々使って使用感を確かめます.気になる箇所が大量に出てくると思うのでちまちま直していきます.
1. 各ファイルタイプごとの最適化
ハイライトはファイルタイプの構文ハイライトに依存するため,ファイルタイプによっては見栄えがイマイチなことがあります. かといってそのたびにグローバルにハイライトを変更すると,ある箇所をなおしたら別のファイルタイプで色合いが壊れるといったことになりかねません.
そこで,各ファイルタイプごとの構文ハイライト名を調べて,そのハイライトを追加します.
例えば diff
ファイルタイプの追加行の色合いは diffAdded
,削除行の色合いは diffRemoved
で決まるので,そこだけ色を変えたい場合はそれらを直接指定してハイライトを定義します.
ハイライト名を知るには :hi
コマンドや :GetHighlightingGroup
を定義して使って調べています.
2. 独自ハイライトを使うプラグイン対応
プラグインの中には独自のハイライトをもっているものがあります.
例えば vim-gitgutter は変更行の印(sign)のハイライトがデフォルトでかなり原色に近い赤・緑・黄色なので,今回のコントラストを抑えたカラースキームには合いませんでした.
ちゃんと変更できるようになっているので,GitGutterAdd
などのハイライトを追加することで対処できます.
3. ステータスラインプラグイン対応
僕はステータスラインに vim-airline を使っているので,airline 用テーマを作成しました.本体側のパレットにある色を極力使うようにすると統一感が出て良いと思います. また,ビジュアルモードの選択色とステータスラインの色を合わせるとさらに統一感が出て良かったです.
まとめ
今回,実用のために結構がんばってカラースキームをつくってみて,(まだまだ改善箇所はありますが)それなりに満足のいくものができました. 配色含めデザインは大変だなぁと感じつつ,なかなか楽しく開発できたと思います.なんといってもフルスクラッチで自分でつくったカラースキームでコードを書くのはテンションが上がって良いですね.
どうしても合うカラースキームが見つからない方や,楽しそうだから作ってみたいという方がカラースキームをつくる際の参考になれば幸いです.