ESLintでファイルの中身によって設定ファイルを切り替える
の続きで、実際やってみたという話です。
雑なメモですがご容赦ください。
ESLint plugin作成
ここではeslint-plugin-fooとしておきましょうか。
package.jsonとindex.jsを作ります。
eslint-plugin-fooという文字列があれば、.eslintrc2.ymlを使うようにします。
ソース
'use strict'; var eslint = require('eslint'); var alternativeCLIEngine = new eslint.CLIEngine({ configFile: './.eslintrc2.yml', }); function preprocess(text, filename) { if (!/eslint-plugin-foo/.test(text)) { return [text]; } var config = alternativeCLIEngine.getConfigForFile(filename); var eslintRules = '/*eslint ' + Object.keys(config.rules).map(function(rule) { return rule + ':' + JSON.stringify(config.rules[rule]); }).join(',') + '*/'; return [eslintRules + text]; } function postprocess(messages) { return messages[0]; } module.exports = { processors: { '.js': { preprocess: preprocess, postprocess: postprocess, }, }, };
こんな感じ。
https://github.com/yukidarake/eslint-plugin-foo
ソースは↑にあげました。
仕組み
ファイルのどこかにeslint-plugin-foo
があれば、行頭に/*eslint no-var:0*/
みたいに付けるという超力技。
動かしてみる
必要なモジュールのインストール
使いたいファイルのあるディレクトリで
npm i eslint npm i yukidarake/eslint-plugin-foo
してください。
.eslintrcを2つ用意
.eslintrc.yml
--- root: true plugins: - foo rules: no-var: 2
と
.eslintrc2.yml
--- root: true rules: no-var: 0
実行
これで準備は整いました!
a.js
// eslint-plugin-foo var a = 1;
というファイルを使って、コメント行の文字列を消したり、戻したりしながら実行してみてください。
./node_modules/.bin/eslint a.js
結果
/private/tmp/a.js 2:1 error Unexpected var, use let or const instead no-var ✖ 1 problem (1 error, 0 warnings)
と出たり出なかったり・・・
ソース中のテキストの有無によって.eslintrc.ymlと.eslintrc2.ymlを切り替えできているようです。
まとめ
この方法をうまいこと使えば同じディレクトリ内でES5とES2015のJSファイルが混在していてもうまいことチェックできたりするのでは?
というアイデアでした。
もっと良い方法や指摘事項等あればぜひ教えてください・・・
SVNの.svnディレクトリを一発で消す
2016年にSVN!?
しかも、Subversion 1.7より前の話!?
(1.7以降はルートにのみ.svnディレクトリがあるので今回みたいなことは起きない)
というのはさておき、困っていたデザイナーさんがいたので救いました
(あと、特に目新しい技術ネタもなかったので。。)
現象
他のディレクトリをまるっとコピーしたことで余計な.svnディレクトリが付いてきて、新しく作ったはずのディレクトリがコミットができない。
A/.svn A/dir1 A/dir1/.svn A/dir1/file1 A/dir1/file2
↑みたいなAディレクトリをBディレクトリとしてコピーしたら、.svnまでコピーしちゃったという感じ。
対応
一緒にコピーしてしまった.svnディレクトリだけを消してやると。
ターミナルでサクッと。
find . -type d -name '.svn' | xargs rm -r
本当は
find . -type d -name '.svn' -print0 | xargs -0 rm -r
とやったほうが安全だけど今回は端折りました。
上記のfindとxargsのコマンドの各オプションの意味は↓の記事が解説がしっかりしているのでオススメです。
Ansibleのshellモジュールでヒアドキュメントが使いたいときー
が、あると思います。
shellモジュールでヒアドキュメントを使うと・・・
コチラのissueにコメントがありましたが、
- shell: | cat <<EOT a b EOT
の結果は
a b
(半角スペースがaとbの前に入る)
という。。
大半のケースでは大丈夫でしょうが、困る場合もあります。
対策
Ansibleのコアディベロッパーが推奨しているらしい方法
scriptモジュールを使う。
http://docs.ansible.com/ansible/script_module.html
ローカルにあるファイルをリモートに転送して実行してくれます。
例えば、
roles/common/file/script.sh roles/common/task/main.yml
な構成をとっていた場合、roles/common/task/main.yml
では
- script: script.sh
みたいに使えます。
これならAnsible特有の問題で嵌ることもないでしょう。
ワークアラウンド
発想の転換に感心してしまったのですが、sedを使って空白を取り除きますw
- shell: | sed 's/^ //' <<EOT | cat a b EOT
これで普通にヒアドキュメントをcatしたのと同じになると。
まとめ
ま、ほんとうは冪等性確保のために、shellモジュールもscriptモジュールも使うなということなのでしょうが・・・
どなたかの参考になれば幸いです。
Google Cloud Vision APIを試してみた
画像を送ったら、画像の中身を解析して、顔とか物とかを判別してJSONで返してくれるというヤツです。
昼休みにざっくりと触ってみたのでメモ。
下準備
こちらのブログが詳しく、大変参考にさせていただいたのでみてください(雑)
ざっくりいうと
というくらい。
料金表によると、月1000リクエストまでは無料っぽいですが、クラウド破産が怖い場合、上記の記事を参考にアラートを飛ぶようにしたほうがよいでしょう(私はアラートが飛ぶようにしましたw)
プログラム
APIキーを付けたCloud Vision APIのURLにbase64エンコードした画像ファイルをJSON形式でPOSTするだけです。
ワンライナーでもいけますが、見づらいのでシェルスクリプトにしておきました。
今回使用した画像はこちら(私のネット上でのアイコンです。スクリプト中のyukidarake.jpeg)
なお、風景写真から物を認識させるとか、人物写真から顔を認識させるのはfeatures
に指定した項目で変わるよう。
今回はLABEL_DETECTION
にしてみました(顔っぽいので、FACE_DETECTION
にしたら結果は空だった・・・)
#!/bin/bash set -ue BODY=$(cat <<JSON { "requests": { "image":{ "content": "$(base64 yukidarake.jpeg)" }, "features": [ { "type": "LABEL_DETECTION", "maxResults": 20 } ] } } JSON ) echo $BODY | curl \ -H "Accept: application/json" \ -H "Content-type: application/json" \ -X POST \ -d @- \ https://vision.googleapis.com/v1/images:annotate?key=API_KEY
実行すると・・・
./vision.sh
こんな結果が。
{ "responses": [ { "labelAnnotations": [ { "mid": "/m/0j272k5", "description": "eyewear", "score": 0.95789468 }, { "mid": "/m/0h8jxfl", "description": "vision care", "score": 0.93333292 }, { "mid": "/m/0jyfg", "description": "glasses", "score": 0.89535505 }, { "mid": "/m/0c_jw", "description": "furniture", "score": 0.84084433 }, { "mid": "/m/0b_rs", "description": "swimming pool", "score": 0.82729644 }, { "mid": "/m/04f6rz", "description": "turquoise", "score": 0.82495272 }, { "mid": "/m/0h8lg0g", "description": "eye glass accessory", "score": 0.799998 }, { "mid": "/m/02_n6y", "description": "goggles", "score": 0.77193254 }, { "mid": "/m/02crq1", "description": "couch", "score": 0.62357479 }, { "mid": "/m/01mzpv", "description": "chair", "score": 0.59412205 } ] } ] }
メガネは認識できているよう。
swimming pool
って・・・
青っぽい画像のシマシマがスイムレーンだと誤って検出されたのでしょう。
まとめ
あんま例がよくなかった気がしますが、いろんな可能性が感じられて楽しいです。
実は、他の画像ではもうちょいうまく検出できました(著作権が気になったので自分のアイコンにしてしまいました。。)
興味持った方は、ぜひ、一度お試しください。
ウチのチームでKPTが根付いた話
本日はあまりにもネタがないため、今所属しているチームでKPTが根付いた話をしたいと思います。
気づいたら1年くらい続いておりすっかりチームの文化になりました(これは本当に素晴らしいことだなと思ってます🌞)
KPTとは何か?
振り返りのフレームワークのことですが、詳しくはググッてくださいw
いろんな企業での事例もあるし、本もいくつか出ていますね。
ソニックガーデンの↓の記事や
クックパッドの↓の記事
なんかは素晴らしいですね!
KPT導入が成功したポイント
(ウチのチームで)導入成功の要因だと思われるモノをいくつかご紹介したいと思います。
KPTの本を買って、みんなで読んだ
チームに入った人には↓の本を読むようにしてもらっています。
わかりやすく、内容もコンパクトなのでオススメです。
毎週決まった日時に繰り返し開催
毎週火曜日、決まった時間に開催してます。
繰り返し決まった時間に行うと習慣化しやすいです。
ちなみに、月曜日は祝日でよく潰れてリズムが崩れるのでオススメしませんw
アナログにやる
当初、デジタルでやっていたのですが、上手くいかず、ホワイトボード+付箋+サインペンのアナログ運用に切り替えてから上手く回り始めた気がします。
司会はみんなで持ち回り
社内Wikiに進行手順をドキュメント化して、誰でも司会役ができるようにしました。
KPTの理解が深まる、KPTのミーティングの時間を自分事として見れるようになるという点で、上手く機能している気がします。
KPTの進行手順自体をKPTで改良
ちなみにKPTの進行手順は「これだけ!KPT」の本に書かれている内容をベースとして、KPTを繰り返す中でチームに馴染むように改良していきました。
だいぶ安定はしてますが、今でもたまに手順を変更することもあります。
たとえば、当初はスタンダードなKEEP,PROBLEM, TRYだけで進行していましたが、途中でTODOという項目を追加したりしています(TRYからやることを選択して、この項目に移動させる。「これだけ!KPT」によれば、KPT2というやり方だそう)
KPTを導入してどんなメリットがあった・・・?
感覚的にはかなりプラスになっていると思います。
- チームで仕事を進めている感が出た
- 非効率・無駄な仕事を見直すいい機会
- チームの問題を指摘して正したりできることで精神的な支えになる(イライラしない)
というあたり。
最後に
KPTオススメです。
興味はあるけど、いまいち導入に踏み切れない人はぜひ↓の本を読んでみてくださいw
オライリー本を全冊購入するといくらなのか?(ワンライナーバージョン)
コチラを見て、頭の体操程度で。
こんなコマンドで
curl -s https://www.oreilly.co.jp/catalog/ | perl -lnE 's/.+"price">([\d,]+).+/$1/ && (tr/,//d, $c++, $s+=$_); END{ say "合計 $c冊 $s円"}'
結果
合計 445冊 1533060円
結構増えてますね。
Reflect.applyとFunction.prototype.applyの速度を計測してみた
ESLintのprefer-reflect
というルールをONにした
最近、Node.js v6が出たのでバージョンアップがてら、ESLintのprefer-reflect
というルールをONにしました。
そして、既存のソースに早速ESLintをかけたところ・・・
警告ががが
既存のソースに早速ESLintをかけたところ func.call(obj, a)
みたいに書いている箇所で警告を受けました。
http://eslint.org/docs/rules/prefer-reflectによれば、下記の古いメソッドはReflect.xxxに置き換えられると。
Reflect.apply effectively deprecates Function.prototype.apply and Function.prototype.call
Reflect.deleteProperty effectively deprecates the delete keyword
Reflect.getOwnPropertyDescriptor effectively deprecates Object.getOwnPropertyDescriptor
Reflect.getPrototypeOf effectively deprecates Object.getPrototypeOf
Reflect.setPrototypeOf effectively deprecates Object.setPrototypeOf
Reflect.preventExtensions effectively deprecates Object.preventExtensions
Functionのcall
やapply
はReflect.apply
に書き換えなさいとのこと。
ESLintのルールに従い、素直に書き換えよう!とは思ったのですが、速度が激遅にならないかが気になりました。
そこで超ざっくり計測
console.time
にてざっくりと。
'use strict'; function log(i) { return String(i); } for (let n = 1; n <= 10; n++) { console.log(`------------${n}回目-----------`); console.time('Function.apply'); for (let i = 0; i < 100000; i++) { log.apply(log, [i]); } console.timeEnd('Function.apply'); console.time('Reflect.apply'); for (let i = 0; i < 100000; i++) { Reflect.apply(log, undefined, [i]); } console.timeEnd('Reflect.apply'); }
結果。
------------1回目----------- Function.apply: 13.736ms Reflect.apply: 11.770ms ------------2回目----------- Function.apply: 13.979ms Reflect.apply: 8.198ms ------------3回目----------- Function.apply: 10.134ms Reflect.apply: 9.899ms ------------4回目----------- Function.apply: 9.800ms Reflect.apply: 11.548ms ------------5回目----------- Function.apply: 11.939ms Reflect.apply: 7.979ms ------------6回目----------- Function.apply: 8.048ms Reflect.apply: 8.330ms ------------7回目----------- Function.apply: 11.209ms Reflect.apply: 12.215ms ------------8回目----------- Function.apply: 11.397ms Reflect.apply: 8.974ms ------------9回目----------- Function.apply: 9.948ms Reflect.apply: 10.000ms ------------10回目----------- Function.apply: 8.923ms Reflect.apply: 11.215ms
結論
遅いということはなさそうなので、安心して使えそう。