Goで怒りのコマンドラインツール作成

業務でgitを使っていると色々あって、時には.gitignoreをignoreしてリポジトリに全ファイルがpushされているなんて事態に出くわすこともあります。
諸々の事情により新しくリポジトリを作成し直すことができなかったため、気合のgit rm --cachedを繰り返そうとしたのですが。。。

f:id:t-miliya612:20180701232846p:plain (写真は別で準備したリポジトリです)

ちょっと手作業だと事故を起こしそうな数だったので、練習がてらgoでコマンド作ってみました。備忘録も兼ねてまとめていきます。

github.com

何してるの

中身はシンプルで、

  • 引数で.gitignoreへのpathを受け取る
  • .gitignoreファイルを1行ずつ読み込む
  • 1行ごとにgit rm --cachedを実行する

くらいしかしていません。

引数で.gitignoreへのpathを受け取る

pathは引数で受け取ることにしました。
flagパッケージを使いたくなるところですが、今回のpathはrequiredのため、optionにしちゃいけないなと。素直にos.Args()でいきます。

flag - The Go Programming Language

os - The Go Programming Language

引数の数と、ちゃんと.gitignoreを指定してるかどうかだけちゃんと見てあげています。

// validate arguments amount
if len(os.Args) != 2 {
    log.Fatal("1 argument should be given.")
}
// get argument
path := os.Args[1]

ignorePath := filepath.Clean(path)
if filepath.Base(ignorePath) != ".gitignore" {
    log.Fatal("arg should specify .gitignore file.")
}

.gitignoreファイルを1行ずつ読み込む

まずはファイルを開きます。deferで閉じてあげるのを忘れずに。

f, err := os.Open(ignorePath)
if err != nil {
    log.Fatal(err)
}
defer f.Close()

次に、ファイルの内容を読み込んであげます。bufio.NewScanner()でいきましょう。

bufio - The Go Programming Language

s := bufio.NewScanner(f)
for s.Scan() {
    ...
}
if s.Err() != nil {
    log.Fatal(s.Err())
}

1行ごとにgit rm --cachedを実行する

最後の段階です。前の章で読み取った1行分の.gitignoreを使ってコマンドを実行してあげたいのですが、そのまえにちょっと整形が必要です。
.gitignoreからコメントアウトされた行と、改行のみの行を省いてあげます。

str := strings.TrimSpace(s.Text())
if isLineValid(str) {
    // execute command
}
...

func isLineValid(line string) bool {
    if line == "" {
        return false
    }
    return !strings.HasPrefix(line, "#")
}

いよいよラスト、コマンドを実行してあげます。goでの外部コマンドの実行はexec.Command()を使用します。

exec - The Go Programming Language

err := exec.Command("git", "rm", "--cached", str).Run()
if err != nil {
    fmt.Println(err)
}

以上です。buildして実行してあげましょう。

exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
exit status 128
REGNORE: 2 files are ignored.

大量のエラーメッセージを吐いてますが、これは既にignoreに追加済みのファイルに対してコマンドを実行した際のものです。ここのエラー処理はお好みに合わせて各位よろしくおねがいします。

おわりに

やっぱりGoはコマンド作るのめちゃくちゃ簡単ですね。。。最後のバイナリ生成の部分、サラッと流してますけど素晴らしいです。
今回はかなりやっつけで書いてますが、もうちょっと公開するに向けてREADMEやhelpオプションなどと整えていきたいです。

Android Test Night#4に参加してきた! #android_test_night

先日、Android Test Nightに参加してきました。
ブログ枠です!

info

testnight.connpass.com

togetter.com

会場がめちゃくちゃオシャレでした。写真撮ってませんが。。。

LT

世界のカンファレンスから~AppiumConf 2018~

  • AppiumConf 2018参加レポ
  • youtubeに動画あり
  • オススメのトーク紹介
    • Appium: The Untold Story
    • Docker-Android: Open Source UI-Test infrastructure for mobile website and android application
    • Layout Automation Testing (GUI)
    • Deep Hacking Appium for Fun and Profit

appiumconf.com

ロンドンで開催された、AppiumConf2018に参加された話でした。お恥ずかしながらAppiumはここで初めて知ったのですが、カンファレンスのセッション一覧を眺めるだけでもテーマが幅広く、ワクワクしてきました。
また、登壇者の@mkwrdさんの写真集も、海外カンファレンスの参加したみを高めてくれました。資料公開お待ちしてます!

2018/07/24 0:35追記
資料共有していただきました!

SDK開発にUIテストを導入してみた

  • SDKならではのテストの難しさ
    • SDKのユーザーは開発者
    • ユーザーのアプリ構成が様々
    • 対応端末が広い
    • 長期間古いバージョンが使われる
  • 課題
    • 自動テストのメンテコスト
    • 手動テストを様々な環境で回したい
    • adhocテストを一つにまとめたい
  • 解決策: UIテスト
    • メリット
    • やり方
      • テスト対象SDKを組み込んだ簡単なアプリを準備
      • 通信やライフサイクル、UIなどをmockやテストライブラリを使って検証
    • 成果

タイトルからして引き込まれたLTでした。SDKなのにUIテストって……?と思いましたが、確かに動作を保証する目的ではそのレベルの抽象度のテストを走らせるのが効果的だなぁと。
また、SDK開発ならではのテストの難しさは非常に生々しく印象的でした。提供側でユーザーの使用状況をコントロールできないつらみをひしひしと感じます……。初めてリリースする際に、そこの戦略をしっかり立てておかないとですね。まさかAndroidX.Xから対応しているとは……(詳しくは資料で)。

Visual Studio App CenterでGitHubのPull Requestを効率よく対応しよう

www.slideshare.net

  • Visual Studio App Center
    • 自動ビルド、テストに加えてアプリ配布やAnalyticsのサポートをしてくれる
    • Github Appができた
    • PR画面でビルド、テストの状況を確認できる

Microsoftが提供するVisual Studio App Centerの紹介でした。 https://azure.microsoft.com/ja-jp/services/app-center/

Githubとの連携はMicrosoftGithub買収完了よりも先に行われていたようですが、CI周りのツール群を一つにまとめられるのは大きいですね。
また、本題ではないですが、GithubのChecks APIも興味深い話題でした。このAPIのおかげで、PRページのChecksタブからビルド結果だけでなく更に詳細な情報を確認することができるようになります。

f:id:t-miliya612:20180623225549p:plain
https://blog.github.com/jp/2018-05-11-introducing-checks-api/#%E6%96%B0%E6%A9%9F%E8%83%BDchecks-api

現在の連携はVisual Studio App CenterとTravis CIのみで、Circle CIは現在連携に向けて開発中だそうです。

blog.github.com

対応を楽しみに待ちたいと思います!

Android Architecture Componentとテスト

github.com

  • AACのLiveDataにテストを書く
    • UnitTest
      • Observerの状態と変更通知、そのタイミングを意識してテストケースを考える
      • テストを書くときはLiveData#observeForever()を使うと便利
    • InstrumentTest(UI)
      • UIテストのケースは、VMのLiveDataにpostすることで実装できる

AAC導入に向けての知見です。登壇者の方も含め、会場にはまだあまりAACを業務レベルで導入している人は少ない様子でした。
LTの中では特にInstrumentTestに関する話が面白くて、ただmainの実装だけではなく、テストを書く際に発揮されるAACの力が感じられて最高でした。Android Architecture Componentsですし、納得です。

Androidテスト全書トーク

peaks.cc

とんでもないスピードでプロジェクトが成立したことで話題になったこの本の著者陣が集まって、トークイベントが行われました。

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

ファシリテーターは、Peaks代表のながのさんです。

twitter.com

なお、父さん(通称パパさん)は現在アメリカにいらっしゃるため、またtarappoさんは所用のため残念ながら不参加でした。。。パパさんのDroidKaigi2018でのUnit Testハンズオンのおかげで僕もテストを書き出せています。

fushiroyama.hatenablog.com

また、このメンバーに加えて、この本の編集校正を担当されているLionasさんもご登壇されました。

twitter.com

トーク内容は以下からどうぞ。必死でメモ取りましたが、内容途中で抜けてるかもです。。。

Android Test Night#4 - Androidテスト全書トーク

めちゃくちゃ中身が濃い時間でした。テストそのものとしても、またアウトプットする、という点でも非常に学ぶべき点が多かったです。
また、ながのさんのファシリテートスキルが高いこと……!恐ろしく話のフリがスムーズでした。リリースは8月末予定、楽しみにしています!


以上、イベントレポートでした。初めてブログ枠として申し込んでみましたが、お楽しみいただけていれば幸いです。
テストはアプリごとに全く事情が違うため、書いているとちょっと寂しくなることもありますが、エモい話もあり、知らない世界もあり、意義のある時間を過ごせました。登壇者の方々、また主催者の方々、ありがとうございました!

参考

  • あの 和田さんの資料もぜひ!

ReactとReduxを一通り触ってみた

Flutterのアーキテクチャ組むとしたらReduxだよね、みたいな話を聞いたので、Reduxのお勉強がてらReactやってみるかという程度の軽い気持ちではじめてみました。忘れないうちに備忘録としてまとめておきます。

React

最近、というのも憚られるほどjs系のライブラリが枯れてきている今日このごろですが、Reactです。単体ではデータフローなどには全く関与せず、純粋なViewを管理するライブラリです。特徴としては大きく2つあります。

Virtual DOM

名前の通り、ブラウザが実際に保持しているDOMとは別のReact内部の仮想DOMです。

f:id:t-miliya612:20180610201857p:plain
https://www.html5rocks.com/ja/tutorials/internals/howbrowserswork/#The_rendering_engine

何でそんなことをするのかというと、ブラウザレンダリングの高速化のためです(超ざっくり)。下の写真はブラウザがhtmlとcssを解析・描画していく流れを示したものです。 このうち、特に重い処理がLayoutPaintingの2つで、これが行われる回数・範囲を如何に減らしていくか、というのが課題になります。
初回のレンダリングは仕方ないですが、ユーザーのアクションや外部からのpush通知などのイベントに応じて一部を描画しなおしたりする際、変更があった部分だけを再描画してあげれば、先の2つの処理による負荷を小さくすることができます。
VirtualDOMを使って事前に現在のDOMとのdiffを取ってあげることで、これを実現しようというわけです。

JSX

Javascriptを拡張したXMLライクな言語で、これを使って描画するコンポーネントを記述していきます。

<div className='container'>
  <h1 className='title'>Hello</h1>
</div>

htmlとは少し文法が異なりますが、大体読めばわかるかな、という感じです。rubyerbのような、ただパースして処理をしてくれるもの、とはちょっと違う感じです。
また、Reactにおいてjsxの使用は必須ではありません。現に、reactの入門書として有名(?)なオライリーのこの本はjsx無しで書かれてています。
余談ですが、vimでjsxのシンタックスハイライトを行う際、htmlとして認識させるのが手っ取り早いやり方みたいです。なるほど、確かに。

実践

この本をやってみました。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

扱ってるテーマはすごくいい感じで、これに沿って公式ドキュメントを読み進めていくといいと思います。誤字がちょっとあるのと、扱ってるmaterial-uiのv1.0がリリースされてだいぶ変わってしまった点を除けば良書でした。

material-ui.com

この本で実装したYahoo! shoppingAPIを利用したアプリケーションです。特に本以外の面白いことはしてませんが、一応添えておきます。

github.com

Redux

Reduxは、Fluxアーキテクチャを実装した(と言われていたりいなかったりする)フレームワークです。

flux

f:id:t-miliya612:20180610202050p:plain
https://facebook.github.io/flux/docs/in-depth-overview.html#structure-and-data-flow

facebook.github.io

公式のこの図が有名ですね。やりたいことは、データの流れを一方向にしか流れないように制御することです。
このサイトによると、

This structure allows us to reason easily about our application in a way that is reminiscent of functional reactive programming, or more specifically data-flow programming or flow-based programming, where data flows through the application in a single direction — there are no two-way bindings.

データ管理が双方向にならない分、アプリケーションのロジックはシンプルにデータの流れを記述するものになるんですね。reactiveって単語が出てくるのも納得です。

登場人物

  • View
    • Reactのコンポーネントやhtmlなど、ユーザーにデータを表示したり、ユーザーからのイベントを受け付けたりするもの
  • Action
    • Viewで発生したイベントを通知するメッセージそのもの
    • いわゆるSOAPのリクエストのようなもの?
    • ActionCreatorを通じて作成される
    • typeプロパティが必須
  • Dispatcher
    • 全てのデータフローの中心のハブ
    • Actionを受け取り、Storeへと転送する
    • 全てのデータの変更はDispatcherを経由してStoreへと送られる
  • Store
    • State(アプリケーションで保持するデータ/状態)を管理する
    • DispatcherからdispatchされてきたActionを受け取り、stateを変更する

Redux

github.com

Fluxの流れに従いながら、少し登場人物が増えたり原則が増えたりしています。 Reduxには3つの原則があるのですが、先に中身の方からまとめていきます。

Fluxとの違い

公式サイトに言及がありました。

Unlike Flux, Redux does not have the concept of a Dispatcher. This is because it relies on pure functions instead of event emitters, and pure functions are easy to compose and don't need an additional entity managing them.

  • ReduxにはDispatcherという概念がない
    • ReduxにはEventEmitterよりも純粋な関数であるということが重要(超訳)
    • 副作用がないため管理が楽

Another important difference from Flux is that Redux assumes you never mutate your data. You can use plain objects and arrays for your state just fine, but mutating them inside the reducers is strongly discouraged. You should always return a new object, which is easy with the object spread operator proposal, or with a library like Immutable.

  • データを決して変更してはならない
    • 毎回新しいオブジェクトを生成して返す必要がある
      • object spread operatorなどを使おう

これは状態管理という側面もありますが、Stateが変更されたことをObserveする際の都合もあります。Stateの変更は元のデータと最新のデータが異なっている、ことで検知されるため、元のデータを書き換えてしまうとObserveできなくなってしまうんですね。

これを踏まえた上で、ReduxではDispatcherの代わりにReducerを使用します。

3つの原則

  • Single source of truth
    • Stateは1箇所で管理する
    • fluxの場合は数まで言及されていないみたい
  • State is read-only
    • Actionを発行する、以外の方法でStateを書き換えてはならない
    • Viewからいきなりstateにsetterで書き換えとかやっちゃだめ
  • Changes are made with pure functions
    • 先に書いた通り

middlewareの概念

Reduxにはmiddlewareという概念があります。例えば、loggerや非同期処理といったものを実現してくれるもので、ActionCreatorで生成されたActionがReducerに渡る前に処理してくれます。

全体像

これまでの内容を踏まえると、以下の図が読めてくるんじゃないかと思います。

ちょっと脱線

ここまで読むと、「原則としてはきれいだけど、じゃあHTTP通信の処理とかどこでやんのさ」という気持ちが湧いてきますね。ReduxをMVPのView部分だけに押し込めて残りは別でやっていく、というのも考えましたが、何かあまり上手いやり方ではない気もします……。

qiita.com

qiita.com

超簡単に要約すると、redux-sagaというMiddlewareを使ってtaskという概念を作り出し、ActionがReducerにわたる前にやっつけてあげよう、というわけです。詳しくは上の記事や、公式リポジトリをどうぞ。

github.com

おわりに

ここ数年reactに苦手意識を持っていたのですが、思っていたよりもシンプルで使いやすそうでした。ほんのちょっとstaticなページを作るのにはやりすぎかな、という感じもしますが、client側でここまでデータの処理ができてるからこそAPIの提供者側はきれいなIFを定義できるんですね。
一方。。。

AndroidかGoかという環境で生きていると、Androidの超リッチなIDEやGoのformatterの恩恵に甘えまくってしまいます。いざjs書こうとなると。。。
今の所Vimeslint入れて書いていますが、formatterは欲しいですね。

@kakakakakku さんに2ヶ月間ブログメンターをしてもらった知見まとめ

唐突に4月頭からブログを書き始めてきました。思えば自己紹介も何もなかったので、改めて。

自己紹介

みぃや、といいます。2017年新卒で通信系の会社に入社し、エンジニアとしてお仕事をしています。普段の業務ではAndroid開発や新規事業系の企画などを行っています。

学生時代は、CSとかけ離れた文学系の学部で文字を書いたり読んだりしてきました。その中で、言葉って、言語って何だっけ?といったところから色んな事があり、気がついたらコードを書き始め、今に至ります。基本情報は受かりましたが、結構断片的な知識で何とかごまかしてきてしまいました。

ブログを始めた経緯

入社して1年、面白そうなイベントにフラフラ遊びに行ったり、技術系の本を読んだりして楽しく過ごしてきました。業務中も会社の人たちから色んな技術系の話題が飛び込んできて、学生時代に夢見た技術にまみれた生活に少しずつ近づけています。
一方、そんな環境の中である程度過ごしてくると、大して何にも身に付いてないのではなんていう恐ろしいことに気づいてきてしまいました。このままじゃあかんということで、とりあえずブログでも始めてみようかと思い立ちましたが、下書きを書いては消し書いては消しを繰り返す日々が続いておりました。
これQiitaにあるなとか、これ本の内容転載してるだけだなとか、最後の公開ボタンがなかなか押せないんですよね。

そんな中、「仕事とブログどっちが大事なの?」などの言葉で知られる@kakakakakkuさんのブログメンティ募集のお知らせを見て、即座に応募してしまいました。これが3月終わりのこと。

kakakakakku.hatenablog.com

やりかた

基本的には自由にブログ記事を書きまくります。はじめにブログ記事数の目標を設定し、記事にできそうなネタを大量に洗い出していきます。ぼくは週に2記事を書くことにしました。
それに従って実際に記事を書き、出来たらアドバイスをいただく形です。

学んだこと&よかったこと

業務に使える

会社の人「このライブラリのことちょっと教えてください」
ぼく「あ、それ先週ブログに書いたんでURL送りますね」
みたいなことが実際に起こりました。
コードを書いたりブログを書いたり、学んだことをアウトプットするにも色んな形があります。正直、理想形はコードになるのかなーなんて思っていましたが、他人が読む前提のドキュメントとして残しておく、という点にブログの強みを感じました。自分用のメモも勿論いいのですが、他人に向けた前提で書かれたものとはちょっと異なったものが生まれてきますね。

色んなタイプの本を読むようになった

自分がブログを書くようになってから、他の人のブログを今まで以上に読むようになりました。そうすると、興味のある技術分野以外のものに出くわすチャンスに恵まれました。 あんまり興味がなかった マネジメント系やいわゆるビジネス書まで、エンジニアの目線で紹介された記事に出会うと簡単に手が出て……出費がちょっとつらくなってきます。

情報収集の本気度が変わった

あんまり良いことではないのかもしれませんが、週に2記事書こうとすると何とかしてネタをひねり出そうとしてくるようになります。楽しかった!だけでは記事に出来ないので、本を読んだりイベントに参加したりするときに「これで何書こうかなー」と、常に完成形を考えながら頭に突っ込むようになりました。
これでまでは「何となく楽しい」でやっていた情報収集でしたが、完成形を意識すると一気にそれではやっていけなくなります。コーディングや技術の世界を憧れ駆動で目指してきてしまったがために、技術系の話題に触れているだけで幸せになってしまい……。冒頭に書いたような、結局何にも残らない収集の原因はこの辺にあったんですね。

反省

書き出すのが遅かった

記事を1本1本逐次的に書いていってしまった結果、週2記事の目標がかなりつらくなった時期がありました。特に先週は土日で2記事書き上げるといったハードなペースになってしまいました……焦った……。
一気に仕上げるのではなく、普段から断片的なメモを残していくスタイルを作っていこうと思います。

ブログに引っ張られすぎた

テーマ選びであれもこれもとやると、ブログのために今週あれやりたかったけど我慢しなくちゃ……と、テーマが縛られてしまうことがありました。あれ、何のために書いてるんだっけ?
個人的に、ブログを書くもともとの目的はインプットを残すこと、副次的な目的として他の人に読んでもらったりとか何かの機会で使えたら、といったものがありました。あまりにブログベースでやりすぎると、特にシリーズものの記事なんて書いてしまうと大変つらいことになります。
ブログは大事だけど、それだけを目的にしちゃいけないなぁと。

今後について

エンジニアとして

自分のキャリアとして、今の所Android楽しいのでAndroid開発を続けていきたいと思っています。一方、最近CSの知識のなさをつくづく実感することが多くなってきました。。。記事を書くにあたって、調べなきゃいけないことだとか何かふわふわしてることだとかが顕著に現れてきました。
そのため、もうちょっと基本的なところについてもやっていきを図っています。今更ながら、アルゴリズム系や低いレイヤーの部分を眺めていきたいと思います。

ブログとして

新しい技術を学ぶ時間、基本的な知識を身につける時間をちゃんとそれぞれ確保していくため、ブログは新しい技術をアウトプットするものとし、更新を最低週1にしようと思います。
一方、CSの知識の勉強の場も何か作っておきたいところです。こっちのテーマをブログにしなかったのは、日付単位で区切りをつけたくなかったためです。テーマごとに、ちょくちょく気づいたことは追加していける形式でやっていけたらいいなと思います。
Githubのtilリポジトリでもやってみるかなぁ。ちょっとこのあたりは模索しつつやっていきたいです。目標はコミット数レベルで切ることになるんでしょうか。

GitHub で使われる慣習的なリポジトリについてまとめてみた

おわりに

とりあえず2ヶ月間続けてみることで、意外と書けるもんだな、という自信が生まれました。正直なところ、今の自分の業務が今やりたいことにとってベストなのかどうかは分かりません。ですが、常に自分がやりたいことをやるってのも現実味のない話ですし、とりあえずやっていける環境作りをする、という意味でもブログチャレンジ(?)は非常に有意義だと思います。

改めまして、筆の遅い僕の尻を根気強く叩いてくれたkakakakakkuさん、ありがとうございました!
今後も募集があるようでしたら、日常に何かもやもやしている人はぜひ門を叩いてみてください。

Android Things事始め

先日、DroidKaigi Codelabs Tourにお邪魔したところ、Android ThingsのStarter Kitをお借りして試すことができました。

f:id:t-miliya612:20180527005402j:plain

やってみたのはこれです。

Android Things Image Classifier

TensorFlowLite使った画像認識!……ですが、既に学習済みのモデルを用意してくれていました。今回は、学習させる部分ではなく、認識させる部分のみを実装します。
ちなみに、全体で75分かかることになっていますが、ハードウェアの実装で40分ほど確保されています。そんなに時間をガッツリ確保できなくても進められます。

まずはサンプルの犬の画像を認識してもらいます。Portuguese Water Dogという犬がいるんですね。ただのビショビショの犬じゃなかった。

f:id:t-miliya612:20180527005452j:plain

光って読めませんが、curly-coated retriever, Border collie or English spinnerと認識しています。画像とはちょっと違いますが、学習済みデータの都合とのこと。大体犬です。

次に、カメラに接続して実際に撮影した画像を認識していきます。
Import文にhardware関連が並んでいるのはちょっと新鮮です。

import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;

f:id:t-miliya612:20180527005513j:plain

iPod……!惜しい!

Codelabは以上です。お試し用なので認識精度はそんなに高くはありませんが、いつものAndroidStudioを使ってIoT向けに遊べるというのは最高ですね。


……と思いながらブラウザで無心にボタンをクリックしていたところ、不思議なメールが来ました。

f:id:t-miliya612:20180527005610p:plain

そして本日、不思議な箱が到着しました。

f:id:t-miliya612:20180527005920j:plain

台湾からの配送で、税関で別途2080円かかりました。

開けてみた様子です。

f:id:t-miliya612:20180527010020j:plain

中にはこんなものが。

f:id:t-miliya612:20180527010041j:plain

箱の裏側に、中に入っているコンポーネントの説明が書いてあります。さすがgoogle……!

f:id:t-miliya612:20180527010100j:plain

内容物は以下の通りです。

  • メインのボード(NXP i.MX7D)
  • ディスプレイ
  • WiFi用アンテナ
  • カメラ
  • USBケーブル
  • ドライバー
  • Rainbow HAT

Android Things向けに開発された、Raspberry Piに接続して利用する多彩な拡張基板です。温度・タッチセンサ、ブザー、LEDディスプレイなど様々な入出力を試すことができます。

www.switch-science.com

サイトの案内に沿って組み立てていきます。組み立て後のセットアップのために、Androidの端末が1台あると便利です。

androidthings.withgoogle.com

完成品がこちら。

f:id:t-miliya612:20180527010155j:plain

ここで電源を入れるとAndroidが起動する……はずだったのですが、この段階ではまだイメージが焼かれていなかったので作業を続けます。

NXP i.MX7D  |  Android Things  |  Android Developers

まずはここからセットアップツールを落とします。Googleアカウントが必須です。

Android Things Console

落としてきたzipファイルを解凍し、中に入ります。

$ ls
README.md                                android-things-setup-utility-macos       quickstart-temp
android-things-setup-utility-linux       android-things-setup-utility-windows.exe

各OS用にツールが用意されています。今回はmacでやっていきます。

$ ./android-things-setup-utility-macos

...
What do you want to do?
1 - Install Android Things and optionally set up Wi-Fi
2 - Set up Wi-Fi on an existing Android Things device

インストールするのでを選択。

What hardware are you using?
1 - Raspberry Pi 3
2 - NXP Pico i.MX7D

購入したモデルを選びます。今回はを選択。

Setting up required tools…
Fetching additional configuration…
Downloading platform tools…
Unzipping platform tools…
Finished setting up required tools.

ツール群のダウンロードが始まります。

Do you want to use the default image or a custom image?
1 - Default image: Used for development purposes and supported by Android
Things Toolkit, a mobile companion app that can be downloaded at
https://goo.gl/rPWhmv. No access to the Android Things Console features such as
metrics, crash reports, and OTA updates.
2 - Custom image: Upload your custom image for full device development and
management with all Android Things Console features.

インストールするイメージを選択します。クラッシュレポートやOverTheAirでのアップデート配信など、製品化を向けたイメージはカスタムのみの機能です。今回はとりあえず動かすのが目的なのでデフォルトイメージを選びます。

Connect your device to this computer:
The USB cable should plug into your board’s USB-C port. If your computer also
has USB-C ports like the more recent MacBooks, you will need to use a USB hub.
Otherwise the board won’t power on correctly.

Once connected, press [Enter] to install Android Things on the device...

KitをPCに繋ぎます。type-cにはハブが必要、とまで丁寧にメッセージが出てきます。接続したらEnter。

Looking for devices… This can take up to 3 minutes.
found device
Unzipping image…
Flashing Android Things. This will take a few minutes…
*Do not disconnect or interrupt!*

バイスが見つかると実際に焼き始めます。いじらずに待ちます。 この辺からLEDが光り始めます。結構眩しいので注意してください。

finished. total time: 124.358s

Successfully flashed your imx7d.
Successfully flashed Android Things…
Would you like to set up Wi-Fi on this device? (y/n)

f:id:t-miliya612:20180527010754p:plain

いずれ終わります。その後Wi-Fiの設定に入りますが、今回はAndroidのアプリを使って行うのでnを選択します。
そして、AndroidスマホAndroid Things Toolkitを起動します。

f:id:t-miliya612:20180527010600p:plain

f:id:t-miliya612:20180527010615p:plain

Kit側に4文字のコードが表示されるので、画面の指示に従って入力します。
その後、WiFiの設定も行います。

f:id:t-miliya612:20180527010631p:plain

ここでKitの動作確認ができます。僕の場合、カメラモジュールが動きませんでした。 つらいので秋葉原で探してきます。

f:id:t-miliya612:20180527010715p:plain
f:id:t-miliya612:20180527010739p:plain

テストの結果にかかわらず、一通り設定が完了です。
Android Thingsのバージョンが、1.0になっていることを確認しましょう(2018/05/27現在)。このバージョンが低いと、codelabのアプリが動きません。 具体的には、rainbow HATのボタンをinitializeするところでコケるみたいです。

あとは自由にアプリを開発するだけです。最後に、参考になりそうなリンクをいくつか貼っておきます。

Healthtech Meetup vol.1に参加したらネイティブアプリの未来がちょっと見えた話

Healthtech Meetup vol.1に参加してきました。
ヘルスケア系のサービスに取り組むスタートアップのエンジニアが集まるイベントで、システム開発の知見だけではなく幅広いテーマでの発表を聞いてくる事ができました。

connpass.com

Main Session

「継続を支える」ライフログの利用と技術 in FiNCアプリ」

株式会社FiNC 森久太郎さん @qsona

行動変容ステージモデルが特に勉強になりました。使うことで便利になる、といった性質ではないアプリにおいて、どうやってユーザーに寄り添っていくかって難しいです。また、WIPとのことだったので省いたものもありますが、機械学習を使った施策も面白かったです。

AI×創薬の最近の事情

株式会社ディー・エヌ・エー 望月正弘さん

  • AI創薬
    • AIを用いた新薬の開発を行う
      • 論文を読ませる
      • 薬剤投与時の遺伝子発現データを用いる
      • 化合物の構造を学習する
  • Fingerprintを使った機械学習
    • 90年代に発見
    • 化合物の特徴を表現したベクトル
    • IT創薬コンテストで、DeepLearningを用いた学習にも対抗できた

唯一のアカデミックな話でした。内容もさることながら、機械学習に明るくない僕でも引き込まれるような分かりやすい構成でした。バズワードとなったDeepLearningを使ったから結果が出るわけではない、耳が痛い話です。。。

新規サービスでGo, GAEを使ってみた話とその振り返り

DeSCヘルスケア株式会社 鶴田拓也さん@o_tyazuke

speakerdeck.com

  • 採用理由
    • サクッと作ってサクッと潰したい
    • 社内の知見を増やす
    • GAEのStandardEnvironmentでRails使えない
  • 開発の流れ
    • Github
    • CircleCI
      • QAブランチごとにGAEのバージョンを作ってデプロイできるように
    • GAE
  • アナリティクス
    • GAE
    • Datastore
    • BigQuery
    • Data Studio
  • 失敗したこと
    • 歩数は最新のものが届くとは限らない
      • iOSのヘルスケアへの書き込みにラグがあるのが原因
      • 対策: 書き込みを待つ、書き込みイベントを発火させる(ヘルスケアを開く)
    • Goのアンチパターンを踏んだ
      • structにcontextを詰めていた

みんな大好きGo言語の話。GAEの導入に際した生の知見です。業務だと既にAWSの環境が整っているため導入は難しいのですが、聞けば聞くほど惹かれていく。。。
また、構成の話も面白かったです。アナリティクスの話は、稼働しているサービスだからこそ得られる経験ですね。

某サービスのリニューアルでECSを導入したよもやま話

株式会社エス・エム・エス 光宗朋宏さん(@t_mitz)https://twitter.com/t_mitz

speakerdeck.com

  • リファクタリングに合わせて既存サービスにECSを導入
  • 理由
  • 他サービスとの比較
    • Google Kubernetes Engine
      • 当時のIAMの仕様とセキュリティ要件がマッチしなかった
      • AWSのナレッジを蓄積させたかった
    • Kubernetes on AWS
      • 学習コストが高い
      • フルマネージドに寄せて簡単に環境構築したい
  • 構成
    • CircleCI
      • 今はテストの実行のみ
      • docker imageのbuild&pushは時間の関係でやめた
    • CodePipeline
      • Githubのブランチを監視して更新があるとデプロイ
    • Logging
      • awslogs driverでCloudWatch Logsに収集
      • 特に困ってない
      • 本番環境にするときはKibanaにするかも
    • ECS
      • 1サービス1タスク定義
      • 1タスクに3つのコンテナ
        • h2o(httpサーバー)
        • rails
        • shoryuken(gem)

打って変わってAWSの話です。普段CircleCIはAndroidのバイナリを生成してくれるサービスという認識だったので、サーバーサイドの話の中で登場するとちょっと新鮮でした。他サービスとの比較検討も、ヘルスケアといったテーマで括る勉強会ならではのものですね。


LT

m3.comを支える巨神の話

エムスリー株式会社 池田貴世志さん(@progrhyme)https://twitter.com/progrhyme

speakerdeck.com

  • 歴史あるサービスを改善し続けている話
  • 問題点
    • 複雑なサービス間通信
    • ビュー要素を再利用できず、各サイトで再実装している
    • API Aggregatorを活用できていない
  • 対策
    • Atlasの導入
      • フロントエンドのHTML生成を担当
      • サービス間連携の標準化を推進
    • DBを直参照していたものをAPI

大量のユーザーを抱えたサービスの設計と戦い続ける話です。m3.comは名前は知っていたのですが、お恥ずかしながらこんな大規模なサービスだとは知りませんでした……。
抽象度の高い設計思想の話ではなく、1システムをこうしたおかげで改善されたという具体的な話は、なかなか調べただけじゃ引っかからないので来て良かったです。

過去の負債と戦う(テクニック編)

株式会社エス・エム・エス 岡田数馬さん(@okazu_dm)https://twitter.com/okazu_dm

speakerdeck.com

  • 改善すべき点(負債)の改善には普段の備えが重要
  • 負債は普段はぼんやりしているもの
    • 特定する必要がある
  • 改善活動を支えるツール
    • New Relic
      • アプリケーションをリアルタイムで監視してくれるサービス
      • 重いEndPointや大量のQueryを探し出してくれる
      • クエリ発行数を60%に
    • Cloud Forecast
      • JVMの負荷も見られる
      • キャパシティプランニング、インフラコストを1-2割減

まさに「推測するな、計測せよ」に則った話です。ネイティブのアプリだと、端末の内部処理をここまで細かく特定している話ってあんまり聞かないような……?
また、ツール群を使って見つけたボトルネックの解消にいたるまでのフローも聞いてみたいです。

iOSでのバックグラウンド歩数同期

株式会社DeNAライフサイエンス 馬場南実さん

  • やりたいこと
    • バックグラウンドで歩数を計測したい
  • バックグラウンド処理
    • androidだと簡単だが、iOSだと制限が厳しい
    • 音楽の再生
      • 再生し続ければ処理を続けられる(無音を再生し続ける!)
    • 位置情報更新を受け取る
      • 地図アプリは閉じてても案内してくれる
    • 電池消耗の課題
  • background fetch
    • iOSの任意のタイミングで呼ばれるタイマー
    • 呼ばれたタイミングで必要な処理を行う
      • 歩数取得
      • ゴールに到達したか
      • push通知表示
    • 呼ばれる頻度は不定
  • サーバーからのpush通知
    • background fetchの補助
    • 通知を受信したタイミングでバックグラウンド処理
    • ユーザーへの表示はされない サイレントプッシュ

ネイティブアプリの話ということもあってか、1番実感しながら聞けたセッションでした。iOSつらいという話は聞いてはいたのですが、まさかここまでAPIが塞がれているとは。。。無論敵わない点はありますが、Androidの豊富なAPIを当たり前に思ってはいけないですね。
また、バックグラウンド処理をめぐる血の滲むような努力は涙無しには聞けません。無音で音楽流しっぱなしはだいぶ賭けに出たやり方ですね……。

メディカルノート開発/インフラのあゆみ

株式会社メディカルノート 河本穣さん(@k12u)https://twitter.com/k12u

speakerdeck.com

  • 気をつけているところ
    • なるべくマネージドサービス
    • IAAC(infra as code)
    • SSM parameter store
    • packer + ansible
    • Terraform workspace
  • 進化の軌跡
    1. シングルインスタンス
      • admin作業でサイトが落ちる
    2. adminインスタンスの分離
    3. ELB化
    4. CDNフルキャッシュ化
      • HTMLコンテンツごとキャッシュ
      • 今はサーバーレスで配信
  • Infrastructure as Code
    • AMIプロビジョニング
      • packer/ansible/CI
      • アプリケーションや環境に依存しないもの
      • rootで動かすもの
    • プロジェクト環境構築
      • プロジェクト環境のセットアップ
      • ネットワーク
      • サーバー構成
    • インスタンス起動時/デプロイ時
      • ライブラリインストール
      • 依存性解決
  • チャレンジしやすいプロジェクトでは積極的に
    • 一方、駄目なものは駄目と言えることが大事
  • チーム
    • 設計レビュー
    • 実装後レビュー
    • 毎週のKPT確認
    • 運用と開発のチームが 半歩はみ出す
      • 非効率性は境界部分に発生しがち
  • おまけ
    • サービス名を絵文字で表現できるようにすると楽

チーム運営の話が特に勉強になりました。半歩はみ出そうとすること、そして半歩はみ出されることの両方を良しとする文化形成は壁の多そうな取り組みです。
また、サービス名を絵文字で表現する、というのも当日Twitterで話題になりました。名前はかっこいいけどスペルに気を使わなきゃいけなかったり、もしくは略称ばかりでこれなんだっけシステムが続出したりするような事案が発生しがちなので、ビジュアルで認知できるのは強みですね。


まとめ

先日病院のお世話になったこともあり、個人的に非常に関心の高い分野のミートアップでした。健康に取り組む人々をどう支援していくか、という戦略的な面から具体的なシステムの面まで、よくここまで散らばったなと思うくらい幅広いテーマの発表でした。
また、個人的にはネイティブアプリ開発のモチベーションが上がった会でもありました。普段開発しているアプリは、webブラウザよりも優れた体験を与えることを目的にしたものが多かったです。PWAなどを代表とするWeb技術群も流行ってきて、ネイティブアプリって今後どうなってしまうんだろう、という不安も抱えていました。一方、ライフログという観点で見ると、そこにネイティブアプリの優位性があるのかなと感じました。AndroidにはFitAPIもあるし、さらにFitbitなどAPIを提供してくれている外部デバイスと組み合わせることもできます。
ちょっと感度を上げながら新しいサービスを眺めていってみたいです。

『DNSをはじめよう』を読んで実際にappドメインを買ってみた

先日、google.appドメインの一般登録を開始しました。

japanese.engadget.com

ネイティブアプリ開発をお仕事としていることもあり、不思議な使命感に駆られて契約してました。その際、先日技術書展4で購入した『DNSをはじめよう』が役に立ったのでまとめてみます。

DNSをはじめよう』について

著者はmochikoAsTechさん、技術書展において750冊売り切りを達成した恐るべき本です。その後もboothにて売れ続けていると言われています。

今は電子版のみです。

mochikoastech.booth.pm

この本のゴールとして、以下のものが挙げられていました。

・ドメインを買うときは何に注意してどこで買ったらいいか分かっている
Whois情報に何を登録すべきか分かっている
・ 障害が起きたときに黒い画面(ターミナル)で dig コマンドや whois コマンドを駆使して原因を調査できる
サイト移管時に「DNS 浸透待ちで 8~24 時間くらいは切り替わりません」みたいなことを言わない
・読む前より DNS が好きになっている

4つ目が刺さりますね。。。

目次

  1. ドメインWhois
  2. DNSの仕組み
  3. AWSのネームサーバ(Route53)を使ってみよう
  4. digとwhoisを叩いて学ぶDNS
  5. トラブルシューティング

感想

サービスの創世記に携わったりしない限り、なかなかドメインの管理に携わることって無くてですね。趣味でいじったとしても、1回紐付けたら後はそのままにしてしまうので……。
本書は、ドメインに関する知識を疑問ベースで丁寧に扱っており、著者のドメイン愛とそれを広めたい思いがとんでもない熱量で伝わってきます。途中で挟まっているドリルもすごく「上手いな」と感じました。
個人的に1番役立ったのは、リソースレコードについて扱っている章です。AやらNSやら、よくわかんないけどマニュアルに沿ってやっていればOKくらいの認識しかなかったので、良い復習になりました。
また、digコマンドやwhoisコマンドも勉強になりました。これでいちいちブラウザからwhois情報を調べなくてもいいんですね……!

中身からは離れますが、実際の書籍自体のクオリティも高いです。半透明の遊び紙、これいくらするんだろう……。技術書、ニッチな分野も対応するせいか商業誌だとこういうこだわりになかなか出会えないのでちょっと嬉しくなってしまいました。

f:id:t-miliya612:20180520215831j:plain
遊び紙

appドメインについて

.appドメインは、googleドメイン登録サービスのGoogle Registryが提供するトップレベルドメインです。大きな特徴としては、HTTPS接続が必須であるということ……のようです。どうやってるんだろう。

Registry – Google

また、google.appドメインの紹介文を提供してくれているので添えておきます。この文章使ってね、とのこと。

Apps make the mobile world go ‘round, and now they have their own more secure home on the web: the .app domain, the most relevant TLD for mobile apps. You can use your .app name to showcase a unique and trustworthy destination, as a relevant download link, for deep linking, or for sharing screenshots, release notes, and reviews. Get your .app domain now to start sharing your app with the world.

せっかくなのでGoogle翻訳に頼ります。

アプリでは、モバイル世界が一巡し、現在はウェブ上により安全なホームがあります。.appドメインは、モバイルアプリにとって最も関連性の高いTLDです。 .appの名前を使用すると、一意で信頼性の高い宛先、関連するダウンロードリンク、深いリンク、スクリーンショット、リリースノート、レビューの共有などを表示できます。今あなたの.appドメインを取得して、あなたのアプリを世界と共有しましょう。

deep linking惜しい……!!

公式サイトのAnnouncementを見ると、

  • 2017/12/14: .app.devをopenなTLDとして、2018年の前半に提供することが最終決定
  • 2018/05/01: リリース計画が確定
    • 03/29-05/01: 商標を持っている人のみ登録可能な期間
    • 05/01-05/08: Early Accessとして、追加料金を払うと登録可能(追加料金はだんだん下がっていく)
    • 0508-: 全体向けに登録開始
  • 2018/05/02: Early Access期間の追加料金に関する方針が決定
    • 05/01-05/05にかけて段々追加料金が下がっていく
    • 追加料金はレジストラによって違う

のプランで進んでいったみたいです。TLDの立ち上げの一連の流れを追うのも面白いです。
ちなみに.devもローンチに向けて動いているようです。これ、本のトラブルシューティングで言及があったやつですね!

登録について

今回、miliya.appドメインを取得しました。
僕はHPをよく読まずに焦ってEarlyAccessの期間に登録してしまいました。やたら高いと思ったら追加料金だったのか……

今回の場合、レジストリgoogle registryなので、レジストラかリセラを探せばよい、とのことになります。
が、お馴染みお名前ドットコムやムームードメインは取扱業者のリストには無く。。。

Registry – Google

ドキドキしながらも海外のレジストラの中から、name.comで登録してみることにしました。ほとんど勘ですが、こんな人気ありそうなドメインで運営してるってことは大丈夫じゃろ、くらいの気持ちです。

流れ

そんなに難しいことはありませんでした。

  1. 05/02: 会員登録 f:id:t-miliya612:20180520214906p:plain

  2. 05/02: ドメインの契約(Paypal使えました。) f:id:t-miliya612:20180520214929p:plain

  3. 05/09: 24時間以内にアカウントにドメインが追加されるよ、とのメール f:id:t-miliya612:20180520214953p:plain

  4. 05/09: 登録完了通知。Whois privacyも追加するといいよ!とのメッセージ。 f:id:t-miliya612:20180520215021p:plain

  5. 05/09: Whois privacyを追加(追加料金あり)。1分くらいで反映完了メールが来ました。 f:id:t-miliya612:20180520215051p:plain f:id:t-miliya612:20180520215106p:plain

お値段

  • domain: $14.99/year
  • Whois privacy: $4.98/year

合計で年間$20くらいです。なかなか高いです。。。

実験

実際にdigwhoisを叩いてみましょう。

; <<>> DiG 9.10.6 <<>> miliya.app
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5651
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;miliya.app.            IN  A

;; ANSWER SECTION:
miliya.app.     300 IN  A   91.195.240.82

;; Query time: 112 msec
;; SERVER: 2400:402f:9f1f:1100:225:dcff:fe1e:ee57#53(2400:402f:9f1f:1100:225:dcff:fe1e:ee57)
;; WHEN: Sun May 20 21:08:32 JST 2018
;; MSG SIZE  rcvd: 55
$ whois miliya.app
% IANA WHOIS server
% for more information on IANA, visit http://www.iana.org
% This query returned 1 object

refer:        whois.nic.google

domain:       APP

organisation: Charleston Road Registry Inc.
address:      1600 Amphitheatre Parkway Mountain View, CA 94043
address:      United States

contact:      administrative
name:         Domains Policy and Compliance
organisation: Google Inc.
address:      601 N. 34th Street
address:      Seattle, WA 98103
address:      United States
phone:        1 202 642 2325
fax-no:       1 650 492 5631
e-mail:       iana-contact@google.com

contact:      technical
name:         Richard Roberto
organisation: Google Inc
address:      76 9th Avenue, 4th Floor
address:      New York, NY 10011
address:      United States
phone:        1 212 565 2633
fax-no:       1 650 492 5631
e-mail:       crr-tech@google.com

nserver:      NS-TLD1.CHARLESTONROADREGISTRY.COM 2001:4860:4802:32:0:0:0:69 216.239.32.105
nserver:      NS-TLD2.CHARLESTONROADREGISTRY.COM 2001:4860:4802:34:0:0:0:69 216.239.34.105
nserver:      NS-TLD3.CHARLESTONROADREGISTRY.COM 2001:4860:4802:36:0:0:0:69 216.239.36.105
nserver:      NS-TLD4.CHARLESTONROADREGISTRY.COM 2001:4860:4802:38:0:0:0:69 216.239.38.105
nserver:      NS-TLD5.CHARLESTONROADREGISTRY.COM 2001:4860:4805:0:0:0:0:69 216.239.60.105
ds-rdata:     41971 8 2 858FEEE8930855598DB109C9705955EDF494FA641ED1CDD07A95C13357E9FD19
ds-rdata:     23684 8 2 3a5cc8a31e02c94aba6461912fabb7e9f5e34957bb6114a55a864d96aec31836

whois:        whois.nic.google

status:       ACTIVE
remarks:      Registration information: http://www.registry.google

created:      2015-06-25
changed:      2018-03-20
source:       IANA

Domain Name: miliya.app
Registry Domain ID: 2CB00A0B8-APP
Registrar WHOIS Server: whois.nic.google
Registrar URL: http://www.name.com
Updated Date: 2018-05-09T03:39:40Z
Creation Date: 2018-05-08T16:00:44Z
Registry Expiry Date: 2019-05-08T16:00:44Z
Registrar: Name.com, Inc.
Registrar IANA ID: 625
Registrar Abuse Contact Email: abuse@name.com
Registrar Abuse Contact Phone: +1.7203101849
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Registrant Organization: Domain Protection Services, Inc.
Registrant State/Province: CO
Registrant Country: US
Name Server: ns1lmy.name.com
Name Server: ns2bkr.name.com
Name Server: ns3cgw.name.com
Name Server: ns4htz.name.com
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of WHOIS database: 2018-05-20T12:06:31Z <<<

ちゃんとprivacy設定も反映されてます!

まとめ

DNSをはじめよう』のおかげで安心してドメイン取得できました。本のゴールにもあった、

サイト移管時に「DNS 浸透待ちで 8~24 時間くらいは切り替わりません」みたいなことを言わない

これ、学生の頃そのまんま喋ってました……お恥ずかしい……。
学生の頃はサークルのHPを作る、みたいな用途でよくわからないまま触っていたドメインDNSの仕組みも、一回理解してしまえばえらく安心感を持って弄ることができますね。こういう本が、エンジニアではないような人達に幅広く届く場にあればなぁと切に思います。
また、せっかく取得したドメインを取得したので早く使っていきたいですね。はてぶろに課金するか、ポートフォリオサイト作るか……迷いますね。