型定義ファイルの管理方法

TypeScript を書いていて、型定義ファイルがライブラリのリポジトリや DefinitelyTyped/DefinitelyTyped にある場合は、npm 経由でインストールしている。


型定義ファイルに漏れがあると、修正して Pull Request を送っている。また存在しない場合は、DefinitelyTyped/DefinitelyTyped に PR している。


ここで、作成してから取り込まれて、npm からインストールできるまでの微妙なタイムラグの間どうやって管理すればいいのか悩んでいる。

現状、DefinitelyTyped/DefinitelyTyped の types2.0 ブランチに PR していて、それが取り込まれていない。
[types-2.0] Add d3-hexbin by heavenshell · Pull Request #12089 · DefinitelyTyped/DefinitelyTyped · GitHub


この取り込まれていないものを、取り込まれるまで使いたい。

とりあえず、現状は `types` というようなディレクトリを作り、その中に、モジュール名でディレクトリを作り、その中に型定義ファイルを入れている。


`types/d3-hexbin/index.d.ts` という風な形で、tsconfig.json の中で、 paths でモジュール名を解決するようにしている。

    "baseUrl": ".",
    "paths": {
      "d3-hexbin": ["types/d3-hexbin/index.d.ts"]
    }

これで、自分のローカルで npm でインストールしたのと同じように、モジュールとして使える。


ただし、これをプライベートのリポジトリに push しているので、その管理方法が手間。管理したくない。

typings はオワコンな雰囲気が出てきているので、使いたくない。
良い管理方法を知らないので、現状はローカルにキャッシュするたびに、何を管理していて、どこに手が入っているかを Issue として管理している。


何か良い方法はないものだろうか。

eslint と tslint を Vim から

textlint.vim を流用。

GitHub - heavenshell/vim-eslint-config: Wrapper for ESLint [deprecated]
GitHub - heavenshell/vim-tslint-config: Wrapper for TSLint


作った理由は textlint.vim と全く同じ。

syntastic-local-eslint.vim とかは system() でパスを調べてるけど、node_modules の位置を見て、eslint, tslint を探す。

似たようなことをしてる人がいたけど、こちらも system() を使ってた。

vim で編集中のファイルを eslint する - Qiita

自分のは Watchdogs.vim とも連携してるので、WatchdogsRun とかすれば良い。

自分用。便利。

最近作った Vim plugin

textlint を今のプロジェクトでは使ってて、textlint を 開いているバッファから行いたい。


先人がすでにいるし、プラグインもある。


textlint の設定ファイルを npm で管理していて、そこから読み込むというのが二つともできない。

また textlint がグローバルに入っていて、node_modules から読み込むことができない。

なので、その両方をできる自分用のプラグインを作った。
GitHub - heavenshell/vim-textlint: Wrapper for textlint

let g:textlint_configs = [
  \ '@azu/textlint-config-readme',
  \ '@example/textlint-config-example',
  \ ]

こんな感じで設定ファイルを書き、`:Textlint` コマンドを実行するで、設定を行い、`:make` コマンドで実行する。

ただ、この `:make` コマンドを実行すると、バックグラウンドで実行してくれない(textlint は node.js でできているので Vim から使うには少し遅い)。

なので、watchdogs.vim とも連携できるようにした。

:Textlint -c @example/textlint-config-example
:WatchdogsRun

エラーがあった場合は、Quickfix が開いてくれるので便利。

Vim-Pokemon 〜あなたが Vim で開いているファイルに潜んでいるポケモン〜

see Pokemon-Emacs 〜あなたが Emacs で開いているファイルに潜んでいるポケモン〜 - Thanks Driven Life

TL;DR

最近は Pokemon Go が流行っているようで、正式サービス開始を待ち望まれているようです。

『Pokemon GO』は、位置情報を活用することにより、現実世界そのものを舞台として、ポケモンを捕まえたり、交換したり、バトルしたりするといった体験をすることのできるゲームです。 このゲームはモニターの中だけで完結せず、プレイヤーは実際に家の外に出てポケモンを探したり、他のプレイヤーと出会ったりしながら楽しむことができます。

面白そうですね。海外でも既にユーザが爆発的に増えており、スマホ片手に街をうろうろする様子などを画像や動画でも目にします。

さて、日本は夏まっさかりであり、暑い日が続いています。そんな中

「私もポケモン探しにいきたいけどまだサービス開始してないし、 そもそも外に出たくない… 」

という Vimmer も多いと思います。

でもよく考えてみてください。ポケモンは何も外だけに居るわけじゃないんです。 昔はゲームボーイにいました。じゃあ Vim にも居るかもしれないですよね。

Vim-Pokemon とは

https://github.com/heavenshell/vim-pokemon

Vim のライブラリーの一つです。効果としては「今開いているファイル名の絶対パス(もしくはバッファー名)で一意に決まるポケモン名を表示する」だけです。

とりあえずいろいろがんばって .vimrc に設定してもらったあと

$ vim /path/to/俺のリポジトリ/github/vim/vim-pokemon/README.md

を実行すると、(おそらく)ファイル名の横あたりに、下図っぽい感じでポケモン名が表示されます。

この場合は ジュゴン が選ばれました。

つまり /path/to/俺のリポジトリ/github/vim/vim-pokemon/README.md にはジュゴンが潜んでいる。豆知識です。

ちなみに 無名バッファー にはフシギダネが居ます。多分。

実装についてちょっとだけ

特に難しいことはしてませんが

  • ファイル名、もしくはバッファ名を seed として乱数をゲット
    • なのでどの環境でもファイル名が同じ = 同じポケモンが出てくる。はず。
  • (もちろんポケモン一覧 s:monsters が変化したら変わりますが…)

これだけです。

少し前に Pokemon-Go におけるポケモン出現率*1 みたいな画像を見たので、出現率に併せて「出やすいポケモン」「出にくいポケモン」みたいな実装をしてたんですが、 あの画像自体デマだったみたいなコメントもあったので、まあいいかってことでとりあえず愚直にリストから取るようにしました。

あとはポケモン一覧はとりあえず初代の 151 匹*2をチョイスしました。他のシリーズ追加すれば勝手に出てくるとおもいます

まとめ

「/path/to/foo にピカチュウが潜んでいたぞ!!」 「ミュウが見つからねえ!!」

みたいな楽しみ方で、エディタ生活に華を添えてください。ポケモン大好き!!

蛇足

あとネタとしてパクらせてもらった、偉大な Emacs ハッカーの @gongoz さん大好き!

Testinfra を使って見る

Ruby の Infrataster ではなく Testinfra

Testinfra aims to be a Serverspec equivalent in python and is written as a plugin to the powerful Pytest test engine

https://github.com/philpep/testinfra

ってある通り Python 版 Serverspec。
テストランナーに PyTest を使っている。

# -*- coding: utf-8 -*-
import re

class TestNginx(object):
    def test_nginx_should_installed(self, Package):
        """ nginx should be installed. """
        nginx = Package('nginx')
        assert nginx.is_installed        
        assert nginx.version.startswith('1.6.1')
          
    def test_nginx_should_running(self, Command):
        nginx = Command('/etc/init.d/nginx status')
        assert re.match(r'^nginx*', nginx.stdout)

    def test_nginx_conf_should_exists(self, File):
        f = File('/etc/nginx/nginx.conf')
        assert f.exists                  

    def test_nginx_confd_should_exists(self, File):
        f = File('/etc/nginx/conf.d')    
        assert f.is_directory

ドキュメントのサンプルは PyTest の関数で書かれていたけど、クラスでも書ける。

$ testinfra -vs test_nginx.py --connection=ssh --ssh-config=~/.ssh/config --hosts="host_name_is_here"

こんな感じに書くと、対象のサーバーに PyTest がテストを実行してくれる。


なお現状バックエンドに MacOSX は対応しておらず動かない。
また

def test_nginx_running_and_enabled(Service):
    nginx = Service("nginx")
    assert nginx.is_enabled

が、service コマンドが見つからないと怒られた。

Flask 0.11 の後方互換がなくなる機能

Flask 0.11 がリリースされた。
Flask 0.11 Released | The Pallets Projects
# ちなみにどうでもいいけど、Flask のコードネームは酒の名前


後方互換がいくつかなくなってるので、まとめてみる。
# 漏れがあったら追記する予定


とりあえず自分のプロジェクト生成ツールで作成した Flask project を起動して試してみただけ。

flask.ext.* が非推奨に

/tmp/virtualenvs/flask_011/lib/python3.5/site-packages/flask/exthook.py:71: ExtDeprecationWarning: Importing flask.ext.cache is deprecated, use flask_cache instead.
  .format(x=modname), ExtDeprecationWarning

こんな感じで、Flask の拡張ライブラリ系で flask.ext.* を使っていると、警告が表示される。
自分のプロジェクトは flask.ext.* を flask_* に変更すればいい。
GitHub - pallets/flask-ext-migrate: A script for migrating extension import syntax.
あるいはマイグレーションツールがあるので、それを利用すると解決する。


ただし、ライブラリ内で使われている(例えば、Flask-Cache)場合は、ライブラリの対応を待つ必要がある。
Flask-Cache は Pull Request が出てたので、取り込まれるのを待つ。
# 自分のプロジェクトの場合、未だに flask.ext.* を使ってたのが、Flask-Cache だけだった


個人的には名前空間的に ext というのに属しているのはわかりやすくて良いし、flask_ とプレフィックスがつくのはイマイチ好きじゃない…。
# ext hook を呼んでいてるのでそのオーバヘッドはもちろんあるだろうけど…。

request.json が非推奨に

API サーバーとして Flask を利用していて、クライアントから JSON をパラメーターとして要求している場合に、よく使われると思うけど、request.json じゃなくて request.get_json() にする必要がある。


メソッドを呼ぶ方がわかりやすいので、良いと思う。

Jinja2 のテンプレートのオートリロード

今まで、アプリケーションを起動したまま、Jinja2 のテンプレートを変更したら、次のリクエストからは、変更されたテンプレートが反映されたが、今回からは TEMPLATES_AUTO_RELOAD を Flask の設定に含めないといけない。
TEMPLATES_AUTO_RELOAD の設定がない場合は、デバッグモードの値を Jinja2 に auto_reload に突っ込んでいる。


本番環境では debug=False にしているので、ちょっと HTML のテンプレートを起動したまま変更…というのをやりたい場合は、TEMPLATES_AUTO_RELOAD にする必要がある。

大きい変更

flask コマンドが追加された。
http://flask.pocoo.org/docs/0.11/cli/
今まで、Flask-Script を使って、Flask にコマンドを追加していた。
それを使わなくても Flask だけでできるようになる(つまり Flask-Script を差し替える必要がある)。
時期を見て置き換えよう…。


他諸々追加になったりしてるものがあるので、何かあったら追記する。
# きになるのが、SESSION_REFRESH_EACH_REQUEST くらいか。

Electron1.0 の起動時のエラー

遊びで作ってる Electron なアプリケーションの electron-prebuilt を 1.0.2 にあげて起動したら、エラーになった。

Cannot find module ‘app’

Cannot find module 'app' - electron - Atom Discussion


ということで、

import electron from 'electron';
import path from 'path';

const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const crashReporter = electron.crashReporter;

というふうに変えたら、いけた。
あと、crashReporter で submitURL を設定してないとエラーになって起動しないので、適当な URL を設定した。