Hatena::ブログ(Diary)

Memo

2017-12-31

[] 2017 年振り返り

f:id:heavenshell:20171231130026p:image

ほぼお仕事のコミット。プライベートな開発があんまりできなかった。

Vim プラグインを幾つか作った程度。

Firefox57 になって Vimperator が完全に死んだので、Vim-Vixen にしたが自分にとって致命的に使いづらかった問題があったので PR 送った。

無事に取り込んでいただいて満足した。


お仕事では大きめのリリースが 6 月、12 月にあってその前後が多少忙しかった。

特に 4~6 月の色が濃いのはリリース前だったため。

リモートワーク

無事に 1 年半続けられた。オフィスでローカル開発してるチームの方々に感謝しかない。

7 月からもう 1 人フルリモート仲間ができた。

同じ悩みを共有できてとても嬉しい。

同時に健康問題にも直面したので課題が浮き彫りになった。


健康面

4 月と 7 月に扁桃腺炎で 2 回倒れた。

4 月は東京出張から帰った後、7 月は大きいリリースが終わった後にホッとしたのか油断した。

ストレス溜めないように気をつけないと。


右耳がなんか詰まった感じがして、突然聴力が落ちた感じがした。左右のバランスが狂って非常に気持ち悪くなった。

1 日経ったら治るだろと思い放っておいたけど治らなかったので、耳鼻咽喉科に行って検査したら、見事に右の聴力が落ちていた。

突発性難聴では無かったのは幸いだった。

一ヶ月ほど週に 2 回ほど通院して治療して元に戻った*1


首と肩

2 月に突然左腕がだるい感じがした。病院を紹介してもらって診てもらったが初見では分からないので 3 月に MRI を受けた。

MRI は初だったけど、面白かった。人生の経験値が上がった気がする。

MRI の結果は神経系には特に異常がないとのことで、薬と湿布を出されて終わり。

運動不足を指摘されたので家の近くのジムで契約して泳ぎだす。

が、5 月、6 月はリリース前で忙しかったのを言い訳にまともに通ってなかった気がする。


7 月になって少し落ち着いたので、また泳ぎだしたら、左肩と左腕に痛みが走るようになった。

昔住んでた場所の近く(今のところから車で 1 時間くらいのところ)の鍼屋さんに行って鍼を打ってもらうも、その日は楽になるが 2 日くらい経つと元に戻る。

9 月になっても酷くなるだけで改善の兆しが見られなかったので、隣駅の整形外科に行く*2

レントゲンを撮ってもらい診断してもらうと、肩関節周囲炎(通称五十肩)であると診断される*3

5 週連続で注射を打ち、できるだけリハビリに通って、リハビリ以外の日は自宅でストレッチをするように言われる。


この時点で肩を垂直に上げることはできなかった。

服を着るのが辛かったり、ライヴで腕を上げたり、飛行機で荷物を棚に入れるのが辛かった。

注射とリハビリが激痛で辛いけど改善の兆しが見えてる。

来年もしばらく続きそう。

買ってよかったもの

近所でマンションを建てる工事をしていて、工事の音が非常にうるさかったので、イヤホンをして仕事をしてたが、耳が疲れるので良いスピーカーがないか探してた。

BOSE のやつとか視聴したが低音を強調されるだけで全く好みではなかった。

他の安いやつも似たり寄ったりだった。

結局ある程度お金をかけてモニタースピーカーにした方が良いと思った。


友人のマスタリングエンジニアが愛用してる ADAM AUDIO の AX シリーズが友人ちで聴かせてもらった凄く良かったし、お勧めされたが机が狭いので置くのが困難だった。

そこで別なのを勧めてもらったのが EVE AUDIO / SC203 だった。

元 ADAM AUDIO の人がスピンアウトして作られたらしく、これも良いよと教えてもらった。

ADAM AUDIO の AX-3 より小さくて自分の机にも邪魔にならない程度に置けてとても良い。

楽器屋に現物があったので、iPhone つなげて聴かせてもらったら、低域が強調されてないしフラットな感じでとてもよかった。

さほど割引してなくてネットで買ったほうが安かったんだろうが、すぐに欲しかったので即購入した。

エイジングが終わった今とても良い音を出してくれてる。

ヘッドホンで聴いてる音がそのまま出てくれてる感じがする。

ピアノのみの曲からデスメタルまで広範囲にきちんと表現してくれてとても気に入ってる。

音楽用(ギター)には物欲が高まったら AX-3 を買おうかなとも思ってる。

ライヴ

今の会社に入って、ハロプロの追っかけやジャニーズの追っかけがいて、経済を回していてる感がとてもしたので、真似てみようと、いけるライヴは行こうと決めた。

6 月からほぼ毎月何かのライヴに行けてとても幸せだった。来年も行ける余裕を持ちたい。

来年の目標

  • 健康
    • 肩の炎症が取れてドクターストップが解除されたら泳ぐのを再開する
  • 体重が少し減ったので、このまま継続して減らしたい

*1:鼻洗浄は慣れないままだった

*2:奇しくも右耳が治りかけくらいの時

*3:ちなみ 80 歳でも 20 歳でも発症するらしい

2017-12-16

[] vader.vim をつかって E2E をやる

この記事は Vim Advent Calendar 2017 16日目の記事です。

「人は生まれたままの姿が一番美しい。ノーパンタイプ」に憧れるけど、風邪をひいちゃうので厚着の vimrc です。


TL;DR

  • 日本語で vader.vim のことを書かれてるのを見たことないので書いた
  • vader.vim 便利

Vim でテスト

以前作ったプラグインに不具合報告を頂くことがあった。手動で動作確認して直したり、新しい機能を作ったりしてて良くないなーと思っていた。

Vim でユニットテストといえば Vim 本体にとてもシンプルな assertion がある。

GitHub - mattn/vim-left-pad

assert を書くだけでシンプルでわかりやすい。

ただし Vim にはテストランナーはないし*1、CI からも使うのめんどくさそうと思っていた。


日本のプラグイン作者界隈では themis.vim がよく使われてるようだが、自分で動かそうとしたけど思ったように動かなかった(完全に自分が悪い)のでめんどくさくなって、まぁ良いかと放置してた。


ある時「大幅に機能追加するから、その前にテスト書いたわ」というとてもありがたい PR をいただいた。

Add tests and fix some issues by letientai299 ? Pull Request #14 ? heavenshell/vim-pydocstring ? GitHub


PR のテストは vader.vim が使われていた。

vader.vim の存在は知っていたけど、README を読んで初見はめんどくさそうというイメージを持っていた。

せっかく頂いた PR を見てみるととてもシンプルな書き方で驚いた。

Given python (def foo with 1 param):
    def foo(arg):
        pass

Execute:
    Pydocstring

Expect python:
    def foo(arg):
        """foo

        :param arg:
        """
        pass

この場合 1 つめのブロックの状態が Vim 上にあることになる。

つまり

def foo(arg):
    pass

というファイルがあり、2 つめのブロックは

:Pydocstring

というコマンドを実行し、その結果が 3 つめのブロックをあらわし

def foo(arg):
    """foo

    :param arg:
    """
    pass

となるのを確認する。

テストの実行方法

$ /Applications/MacVim.app/Contents/MacOS/Vim -Nu minimal_vimrc -R '+Vader! *.vader'

こんな感じで Vim から vader を起動し実行する。

Mac だとシステムの Vim は古いので MacVim を指定する。

普段使いの vimrc を使うよりもシンプルな vimrc を指定した方が良いので、テスト用の vimrc を用意する。

set nocompatible
filetype off
" Clear all rtp
set rtp=$VIMRUNTIME

" Add vader.vim to rtp
set rtp+=./vader.vim

" Add pydocstring folder into rtp
set rtp+=../
filetype plugin indent on

CI で動かすように テストファイルが置いてあるディレクトリに vader.vim を置く。

これで Run time path に vader.vim が追加されて、vader.vim が動くようになる。

vader.vim の印象

関数単位のユニットテストというよりも E2E のテストライブラリ。

基本的に Execute ブロックに Vim で実行するコマンド(大抵はプラグインのコマンド)を記述し、コマンドの実行結果を Expect ブロックに書くため、xUnit や RSpec 系のテストの書き方と違って Vim に特化した DSL という感じがする。

コマンドを実行してその結果がどうなっているかというのを確認するというのに特化していると思う。

vader.vim での assertion

とはいえ vader.vim では Expect ブロックに結果を書いてテストするが assertion もかける。


vim-prettier という Prettier を Vim から実行して整形するプラグインを書いた時はそれも使った。

vim-prettier/prettier.vader at master ? heavenshell/vim-prettier ? GitHub


まとめ的なの

Vim script はスクリプトスコープな関数をテストから簡単に呼べなくて、テストを書くのが面倒だと思っていたが、E2E から始めりゃいいんだと気づかせてくれた。

vader.vim の PR を頂いた後に自分でテストランナーとか書いてみたけど、vader.vim で良いかと思うようになった。


個人的なポリシーとして自分の Vim プラグインは極力外部のものに依存したくないが、テスト系は例外とした。

(プラグイン本体を使うのにインストールされてなくても影響ないため)


とにかく簡単にテストを始められるのでオススメ。

*1:Vim 本体のテスト用にはあるが流用しがたい

2017-10-19

[] Misspell を Vim から呼べるようにした

GitHub - heavenshell/vim-misspell: misspell for Vim.

Misspell が便利だったので Vim から呼べるようにプラグイン化した*1


直接 buffer を misspell に突っ込んだら Vim が SEGV したので channel 経由で入れたらうまくいった*2

便利。

*1:多分 ale にはないはず

*2:原因を追求する気力がない

2017-07-17

[] MacPorts + MySQL5.7

プライベートな環境を久々に更新しようと思ってやったら思いの外はまった。

仕事は homebrew だけどプライベートマシンは MacPorts を使ってる。

*1


Python3.6.0, MySQL5.6 だったので Python3.6.1, MySQL5.7.17 にするかとports upgrade outdated して、MySQL を新規にインストールしようとしたらどハマりしたのでメモ。


入れる先。

  • /opt/local/var/run/mysql57
    • chown _mysql:_mysql /opt/local/var/run/mysql57
  • /opt/local/var/db/mysql57
    • chown _mysql:_mysql /opt/local/var/db/mysql57
  • /opt/local/var/log/mysql57
    • chown _mysql:_mysql /opt/local/var/log/mysql57

`$ sudo -u _mysql /opt/local/lib/mysql57/bin/mysqld --initialize` をするとに権限がないと怒られるので、`--tmpdir=/tmp` をつける。

`$ sudo /opt/local/lib/mysql57/bin/mysqld --initialize --user=_mysql --tmpdir=/tmp`


これでログに色々非推奨になったものとかが出てくるので、まずは my.cnf をきれいにする。

 innodb_large_prefix
-innodb_file_format=Barracuda
-sql_mode="NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES"
+sql_mode="NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER"
+explicit_defaults_for_timestamp=1

これで非推奨な警告らしいものは消えた。


起動したはずだからログに出てるパスワードを使って cli から接続してみると、

Error: Can't connect to local MySQL server through socket '/opt/local/var/run/mysql57/mysqld.sock' (2)

が出た。


/opt/local/var/run/mysql57 に mysql.sock を touch し chown _mysql しておく。

それでもまだ同じのが出るので、ググったら、

`secure-file-priv` とやらを設定する必要がありそうだ。

+secure-file-priv=/opt/local/var/db/mysql57/files

/opt/local/var/db/mysql57/files を 770 に設定。


再度実行。

2017-07-17T04:45:09.183964Z 0 [Warning] Setting lower_case_table_names=2 because file system for /opt/local/var/db/mysql57/ is case insensitive
2017-07-17T04:45:09.184760Z 0 [Warning] You need to use --log-bin to make --binlog-format work.
 100 200 300 400 500
 100 200 300 400 500
2017-07-17T04:45:11.707991Z 0 [Warning] InnoDB: New log files created, LSN=45790
2017-07-17T04:45:11.755651Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2017-07-17T04:45:11.815967Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: b7c42696-6aaa-11e7-ab9a-2c830cb15594.
2017-07-17T04:45:11.836664Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2017-07-17T04:45:12.110979Z 0 [Warning] CA certificate ca.pem is self signed.
2017-07-17T04:45:12.140515Z 1 [Note] A temporary password is generated for root@localhost: yMPR*aN3jPs.
2017-07-17T04:45:50.765696Z 0 [Warning] Insecure configuration for --secure-file-priv: Location is accessible to all OS users. Consider choosing a different directory.
2017-07-17T04:45:50.766060Z 0 [Note] /opt/local/lib/mysql57/bin/mysqld (mysqld 5.7.17-log) starting as process 10452 ...
2017-07-17T04:45:50.768018Z 0 [Warning] Setting lower_case_table_names=2 because file system for /opt/local/var/db/mysql57/ is case insensitive
2017-07-17T04:45:50.768420Z 0 [Warning] You need to use --log-bin to make --binlog-format work.
2017-07-17T04:45:50.769777Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2017-07-17T04:45:50.769812Z 0 [Note] InnoDB: Uses event mutexes
2017-07-17T04:45:50.769827Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2017-07-17T04:45:50.769898Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2017-07-17T04:45:50.770818Z 0 [Note] InnoDB: Number of pools: 1
2017-07-17T04:45:50.770961Z 0 [Note] InnoDB: Using CPU crc32 instructions
2017-07-17T04:45:50.773358Z 0 [Note] InnoDB: Initializing buffer pool, total size = 512M, instances = 1, chunk size = 128M
2017-07-17T04:45:50.821204Z 0 [Note] InnoDB: Completed initialization of buffer pool
2017-07-17T04:45:50.880435Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2017-07-17T04:45:50.897177Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2017-07-17T04:45:50.897331Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2017-07-17T04:45:50.933367Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2017-07-17T04:45:50.934408Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2017-07-17T04:45:50.934428Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2017-07-17T04:45:50.934644Z 0 [Note] InnoDB: Waiting for purge to start
2017-07-17T04:45:51.059136Z 0 [Note] InnoDB: 5.7.17 started; log sequence number 2534561
2017-07-17T04:45:51.059358Z 0 [Note] InnoDB: Loading buffer pool(s) from /opt/local/var/db/mysql57/ib_buffer_pool
2017-07-17T04:45:51.059568Z 0 [Note] Plugin 'FEDERATED' is disabled.
2017-07-17T04:45:51.061839Z 0 [Note] InnoDB: Buffer pool(s) load completed at 170717 13:45:51
2017-07-17T04:45:51.069359Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2017-07-17T04:45:51.069387Z 0 [Note] Skipping generation of SSL certificates as certificate files are present in data directory.
2017-07-17T04:45:51.070018Z 0 [Warning] CA certificate ca.pem is self signed.
2017-07-17T04:45:51.070075Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory.
2017-07-17T04:45:51.077066Z 0 [Note] Server hostname (bind-address): '127.0.0.1'; port: 3306
2017-07-17T04:45:51.077602Z 0 [Note]   - '127.0.0.1' resolves to '127.0.0.1';
2017-07-17T04:45:51.077688Z 0 [Note] Server socket created on IP: '127.0.0.1'.
2017-07-17T04:45:51.093262Z 0 [Note] Event Scheduler: Loaded 0 events
2017-07-17T04:45:51.093377Z 0 [Note] Executing 'SELECT * FROM INFORMATION_SCHEMA.TABLES;' to get a list of tables using the deprecated partition engine. You may use the startup option '--disable-partition-engine-check' to skip this check. 
2017-07-17T04:45:51.093393Z 0 [Note] Beginning of list of non-natively partitioned tables
2017-07-17T04:45:51.106188Z 0 [Note] End of list of non-natively partitioned tables
2017-07-17T04:45:51.106279Z 0 [Note] /opt/local/lib/mysql57/bin/mysqld: ready for connections.
Version: '5.7.17-log'  socket: '/opt/local/var/run/mysql57/mysql.sock'  port: 3306  Source distribution
 $ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17-log

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

動いた。大変だった。

*1:古いバージョンとか簡単に入って便利

2017-06-18

[][] vim-noqalign を作った

同僚氏が noqalign と言うツールを作った。


今のお仕事では Python の `__init__.py` にモジュールを import する。

import だけしてるので flake8 対策として `# noqa: F401` をつけるが、これを面倒と感じた同僚氏が自動で入れるようなツールを作った。


お仕事が佳境な状況だったけど、息抜きに Vim plugin から使えるようにした。

GitHub - heavenshell/vim-noqalign: noqalign wrapper for Vim

超便利!

2017-05-05

[] vim-prettier を作った

tl;dr

GitHub - heavenshell/vim-prettier: Prettier-Eslint-Cli for Vim


Prettier と言う JavaScript のフォーマッターがある。

こいつ単体ではお仕事で設定している ESlint の設定とは関係なくフォーマットするが、prettier-eslint と言うのがあり、これを使えば ESLint の設定通りにフォーマットしてくれる。


で、フォーマッターはエディタから設定したくなる。

オフィシャルのドキュメントには以下のように使えばいいよとある。

autocmd FileType javascript set formatprg=prettier\ --stdin
autocmd BufWritePre *.js :normal gggqG

お手軽だけど、同期的に動く。

そして Prettier は速くはない。

当然 Vim から使えば、その間ブロックされる。

おそらく neoformat とやらも同期で動く。

https://github.com/sbdchd/neoformat/blob/master/autoload/neoformat.vim#L82

Golang の Fmt なんかは速いので同期でも問題ないが、 Prettier は同期では辛い。


というわけでいつも通り Vim の job を使って作った。

ただ、いくつか罠があった。


出力先がバッファ

job は出力先にバッファなファイルを選択できる。

この場合はフォーマットした結果をバッファにて書き換えたいから、バッファを選択してみた。

let s:job = job_start(cmd, {
        \ 'callback': {c, m -> s:callback(c, m)},
        \ 'err_cb': {c, m -> s:error_callback(c, m)},
        \ 'in_io': 'buffer',
        \ 'in_name': file
\ })

こうすると、現在開いているバッファ(file で指定しているバッファ)に追記される。

追記じゃなくて、書き換えてほしい。


出力先がバッファ
let s:job = job_start(cmd, {
        \ 'callback': {c, m -> s:callback(c, m)},
        \ 'err_cb': {c, m -> s:error_callback(c, m)},
        \ 'in_io': 'file',
        \ 'in_name': file
\ })

こうすると、現在開いているファイルをバックグラウンドでフォーマットした結果に書き換える。

現在開いているバッファは書き換わる前の状態。

この状態で :e! でファイルを開き直したら、書き換わった状態に変わる。

当然ファイルが書き換わってるので、フォーマットを実行したらファイルが保存される。


前に作った ESLint の --fix モードもこの方式で実装した*1

vim-frontier/eslint.vim at master ? heavenshell/vim-frontier ? GitHub


Vim-Swift などもこんな感じで行っている。

vim-swift/fmt.vim at master ? dictav/vim-swift ? GitHub


保存と同時に実行するという制約をつければいいが、なんか釈然としない。

せっかく stdin で受け取れるので、フォーマットを実行したら、保存されずにそのままにしてほしい。

他にないかなと探したら、 id:haya14busa さんの GitHub - haya14busa/vim-gofmt: Formats Go source code asynchronously with multiple Go formatters. でおおっと思った実装がされていた。

Add silent for avoid message by heavenshell ? Pull Request #1 ? haya14busa/vim-gofmt ? GitHub *2

tmp なファイルにフォーマット後のコードを吐き出して、ファイルを読み込んで現在のバッファを全て消してバッファを書き換えていた。


prettier は stdout でフォーマット結果を返してくれるので、job の callback で受け取ってリストに追加、 exit_cb で追加されたリストの値で復元とすれば行けた。

*1:あとで書き換えるかも

*2:最新のコミットで改善されてたようだけど

2017-03-31

[][] Vim を mocha から実行する際の注意

QuickRun を利用して、 Vim から各種テストフレームワークを実行してる。

GitHub - heavenshell/vim-quickrun-hook-unittest: Quickrun hook for enable to unittest by selecting method.

mocha も実行できるようにしたけど、mocha.opts に自分のプロジェクトのヘルパーファイル名 js ファイルを読み込んでるとエラーになるのがわかった。

--require test/helper.js
--require babel-register
--recursive

こんなのがあると、テストの実行が、package.json とかがあるディレクトリから実行すると問題ないが、テストファイルのあるディレクトリから実行すると、 `test/helper.js` が実行ファイルからの相対パスとなって、そんなファイルないと怒られる。


結局アドホックに mocha.opts の内容を QuickRun 実行時に読み込んで `--require` がある行を mocha の cli オプションに渡すことにした。

そしてファイルが `.js` で終わるファイルは多分ローカルプロジェクトのものだろうという雑な感じで、フルパスに変換してやる。


ということで、テストファイルの特定のテストを実行できるようになった。