生涯未熟

生涯未熟

プログラミングをちょこちょこと。

3連休を使ってしょうもないものを作ってしまった

素敵な3連休、皆様どうお過ごしでしょうか?

意識の高いエンジニア各位におかれましては、きっとエンジニアリングを磨き上げることに腐心なさっていることでしょう。

さて、そんな中「3連休中にアホなもの作りたい」という欲求を抑えきれずにアホなものを作ってしまいました。

その名も「go-kiriban」

github.com

なにこれ?

簡単に言うと「キリ番のプロセスIDがあればポップアップで教えてくれます」

f:id:syossan:20170717144027p:plain

なんで私はこんなものを作ってしまったのか・・・

技術的なお話

ここからは真面目に技術的な話をします。

今回のこのツールを作るに当たって、ザクッと以下のような仕様がありました。

  • goをデーモン化する
  • プロセスIDの取得
  • キリ番のプロセスIDがあれば何かしらで通知する

とりあえずこんな感じで実装進めていけばいけるでしょ、って謎の根拠を元に作り始めました。

goをデーモン化する

goのデーモン化については標準で備えているものがないため、自力でやる or ライブラリに頼るの二択になります。

自力でやるの選択肢を取る場合、

qiita.com

の記事が参考になるかと。

今回は楽にサクサクっとやりたかったので、ライブラリに頼ることにしました。

使ったライブラリはこちら。

github.com

コードの中身見たら分かるように、windowsdarwinfreebsdといった主要なOS毎に分けてあります。
とりあえずMacのみ対応させようと思ったので、launchdの仕組みを使ったdarwinのパッケージを使っていきます。

使い方はREADMEに書いてある通りで、Exampleの // Do something, call your goroutines, etc と書いてあるところに好きな処理を書いていく流れになります。

これで、goのdaemonizeは完了。

プロセスIDの取得

プロセスIDの取得にはこちらを使いました。

github.com

README・wikiともに詳しい説明がないので、気合でコード読んでいきましょう。

今回の場合では、 プロセスの一覧を取得プロセスのIDを参照 という2点を実現するために、以下のようなコードになりました。

processes := ps.Processes() // プロセスの一覧を取得

for _, p := range processes {
    fmt.Println(p.Pid()) // プロセスのIDの参照
}

go-psの中身はそんなに小難しくないので、使う分には困らないはず。

というわけでプロセスに関しても完了。

キリ番のプロセスIDがあれば何かしらで通知する

ここまではスイスイ出来たのですが、ここからがかなり難関でした。

最初、実装を考えた時に私の頭にあった通知形式はよくある右上にシュッと出てくる通知でした。

ただし、これをlaunchdに登録したプログラムから exec() で実行しようとすると、上手く動かないという問題にぶち当たりました。

原因としてはこの辺りだと思われるのですが、

apple.stackexchange.com

ちょっと提示されている解決法が良く分からなかったため、別のアプローチを取ることにしました。
それは display notification ではなく、 display dialog を使うアプローチです。

display dialog だと、表示の際にコントロールがダイアログに移ってしまうため、あまり使いたくなかったのですがとりあえず3連休中に作りきってしまいたかったために、止む無く使用することに。

こちらだと、launchdから exec() で実行しても動きます。

あとは、 giving up after 5 とかつけて良い感じに◯秒後にダイアログが消えるようにしたりとか。

完成

これでツールが完成しました!

実際は、同じプロセスIDの通知をしないようにoffsetつけたりとかしたのですが、その辺の細かいところはコード見てみてください。

たまには実用性とか何も考えずに、作ってみたいネタなツールを作ってみるのもありですね。

プログラミングは何も考えず楽しくやりましょう!!