上京エンジニアの葛藤

都会に染まる日々

husky コードリーディングメモ

今まで雰囲気で TypeScript (node.js) を書き続けていたので OSS のコードを読みながら少し真面目に勉強しようと思いました。

早速 husky のコードリーディングをしたので、記録としてメモを残します。 github.com

husky は Git Hooks を簡単に設定できるようなツールで、CLI ツールなのでボリュームも少なくて読みやすかったです。

コードリーディング

エントリーポイント

try {
  // Run command or show usage for unknown command
  cmds[cmd] ? cmds[cmd]() : help(0)
} catch (e) {
  console.error(e instanceof Error ? `husky - ${e.message}` : e)
  process.exit(1)
}

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/bin.ts#L36-L42

cmds には実行可能なコマンドが定義されている
引数の cmd が存在していれば対象の関数が実行されるような仕組み
存在しなければ help コマンドが実行され、引数の 0 は process.exit(0) で正常終了させるために渡される


function help(code: number) {
  console.log(`Usage:
  husky install [dir] (default: .husky)
  husky uninstall
  husky set|add <file> [cmd]`)
  process.exit(code)
}

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/bin.ts#L5-L12

cmds には install, uninstall, set, add, -v というコマンドが用意されている
cmd は process.argv で受け取れる
nodejs.org


const cmds: { [key: string]: () => void } = {
  install: (): void => (ln > 1 ? help(2) : h.install(x)),
  uninstall: h.uninstall,
  set: hook(h.set),
  add: hook(h.add),
  ['-v']: () =>
    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires
    console.log(require(p.join(__dirname, '../package.json')).version),
}

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/bin.ts#L25-L33

-v の場合 package.json に書かれている version を参照するような工夫がされている

husky install

const git = (args: string[]): cp.SpawnSyncReturns<Buffer> =>
  cp.spawnSync('git', args, { stdio: 'inherit' })

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/index.ts#L9-L10

git が入っているかチェック
子プロセスを生成して git rev-parse を実行する
rev-parse なのは特に意味はなさそう

nodejs.org


  if (!p.resolve(process.cwd(), dir).startsWith(process.cwd())) {
    throw new Error(`.. not allowed (see ${url})`)
  }

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/index.ts#L29-L31

husky は原則 .git と同じ階層に入れる必要がある
現在の dir に入れれるかチェック

別の project に husky を入れる場合はこんな感じでできる https://typicode.github.io/husky/#/?id=custom-directory


  if (!fs.existsSync('.git')) {
    throw new Error(`.git can't be found (see ${url})`)
  }

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/index.ts#L34-L36

.git がカレントディレクトリに存在しているかチェック


  try {
    // Create .husky/_
    fs.mkdirSync(p.join(dir, '_'), { recursive: true })

    // Create .husky/_/.gitignore
    fs.writeFileSync(p.join(dir, '_/.gitignore'), '*')

    // Copy husky.sh to .husky/_/husky.sh
    fs.copyFileSync(p.join(__dirname, '../husky.sh'), p.join(dir, '_/husky.sh'))

    // Configure repo
    const { error } = git(['config', 'core.hooksPath', dir])
    if (error) {
      throw error
    }
  } catch (e) {
    l('Git hooks failed to install')
    throw e
  }

https://github.com/typicode/husky/blob/840c4164d06d3c412caf63a9c9d7ca1af15f2165/src/index.ts#L34-L36

最後に .husky/ に shell をコピーして、git の core.hooksPath に .husky を設定
.husky/ 以下には commit-msg, pre-commit が hook と用意されて実行されるようになる

以上です。

FILCO 漆塗りリストレストを買った

FILCO 漆塗りリストレスト 摺漆塗り Sサイズを購入しました。

こんな感じです。

写真の通りいつも HHKB を使っているのですが、最近手首のだるい気がしたので初めてリストレスト (パームレスト) を導入しました。

電子バードから出ている公式の物と迷いましたが、デスクをオイルフィニッシュで仕上げた集成材を使っていて少しテイストが違う方が良かったので FILCO にしました。

FILCO & HHKB セットで利用されている人は多いと思いますが、使用感をレビューします。

使用感

漆塗りでマットブラックに仕上げられていて見た目はかっこよく高級感もあります。

幅も HHKB より 1cm ぐらい大きめでサイズは Sサイズがちょうどです。

裏面には写真のように両端に滑り止めが貼られていてリストレストが動くことはありません。

高さは若干リストレストの方が高いですが、今のところ違和感は感じません。
気になる方は気になるかも知れません。

僕はタイピング時のホームポジションも変で、キーに対応する指使いも間違っているのでリストレストに置いたままタイピングするのが若干慣れないです。
これを気に矯正してもらいます。

価格は5000円ほどで安い木を加工した方が安上がりですが面倒なので、今のところ満足しています。

「魚偏漢字神経衰弱」というアプリを作った

iOS, Android 向けに「魚偏漢字神経衰弱」というアプリを作ってリリースしました。

魚偏神経衰弱

魚偏神経衰弱

  • Shota Okunaka
  • ゲーム
  • 無料
apps.apple.com

play.google.com

どんなアプリか

タイトルから予想がつくと思いますが、魚偏の漢字のカードで神経衰弱ができるミニゲームアプリです。

現在、1人用プレイのみで2つのモードが遊べます。

  • のーまるモード
    フィールドの30枚のカードを全て揃えられたターン数を競うモード

  • 3分間耐久モード
    3分間に揃えられたペア数を競うモード
    フィールドの30枚のカードを取りきると再度カードが配られます

なぜ作ったか

普段は Web開発が本業ですが、ゲームが好きなのでゲーム開発にチャレンジしてみようという軽い感じです。

元々物作りが好きで以前は個人開発をちょくちょくしていましたが、最近あまりできていませんでした。
新しい技術を学ぶ自由研究として GW に触ったのがきっかけで少しずつ開発をしていました。

神経衰弱を題材にしたのはゲーム開発はプログラミングだけでなく、画面デザインや SE など作らなければならないものが盛り沢山なので、ゲーム内容が単純なものが良いと思ったからです。

ただ一般的なトランプの神経衰弱だとありきたりなので、魚偏の漢字を題材にすることでよく似た漢字ばかりになり難易度も上がり、面白い要素になるかと少しひねってみました。

1人で神経衰弱ができるだけの単純なミニゲームアプリなのですが、開発期間はリリースまで約2ヶ月かかりました。

魚偏漢字神経衰弱を支えている技術

支えている技術というと大袈裟ですが...せっかくなので利用した技術 (ツール) などをざっくり紹介したいと思います。
僕はプログラミング以外は素人ですが、プログラミング以外も極力自分で作りながら各工程を学びたいと思ったので以下の技術 (ツール) を利用しました。

プログラミング

GameEngine は過去に少し触ったことがある Unity を使いました。
ググれば tips がたくさん出てきて、自分の場合無償で利用できたので負担なく開発を進められました。

ライブラリなど細かいところは、アニメーション周りで DoTween を使っていたり、イベント処理周りで UniRx を使っています。

assetstore.unity.com

assetstore.unity.com

ほとんどゲーム開発をしたことがないので、改善点はたくさんあるかもしれませんが快適に進められました。

フォント

フォントはフリーフォントを利用しました。
漢字がテーマなので和テイストにしてみました。

衡山毛筆フォント opentype.jp

源流明朝 github.com

画像素材

カードの絵柄もフリー素材を利用して、SeaShore を使って加工しました。

www.ac-illust.com

Seashore

Seashore

  • Robert Engels
  • グラフィック/デザイン
  • 無料
apps.apple.com

ゲームは画面 (見た目) が大切ですが、画面デザインが苦手でハリボテな素人感丸出しから抜け出せませんでした。
今後勉強しながらブラッシュアップしていきたいです。

SE

魚偏なので、波の音のような BGM にしてみました。

ゲーム内音楽 (SE) は趣味で DTM をしていたこともあり、Splice からイメージにあったネタを落として Logic Pro でサンプリングしました。
Splice はカードをシャッフルする音などゲーム音楽で利用できそうなネタもたくさんあって便利でした。

splice.com

サブスクで利用したい時だけ 9.99$/month で使えるのも個人開発者には優しいです。

今後の展開

開発を進めているとやるべきことが多すぎて先が見えなくなってきたので、一先リリースを目標にしていました。
実装したい機能を全て実装してリリースすることができなかったので今後は以下のような機能を開発予定です。

  • ランキング機能 元々ランキング用の APIGolang で作って GAE で動かしていたのですが、サーバーのコードを極力書きたくなかったり (本当は書きたいけど工数的に無理) 運用が面倒なので Firebase で作り直す予定
  • プレイ結果の Tweet 機能 プレイ結果の画像をサーバーで作成して Tweet できるようにしたい
  • 様々な解像度対応 UI の実装が悪く端末によっては上手く表示できなかったりするので対応していきたい
  • オンライン対戦機能 オンラインで2人対戦できるようにしたい

感想

  • ゲーム開発は総合格闘技
    ゲーム開発は時間がかかり多様なスキルが必要なことは知っていましたが、実際作業すると想像以上に大変でした
    ここまで単純な2Dゲームですら2ヶ月かかったので、3Dでオンラインプレイができるゲームは流石に難しいだろうなと思いました
    今回は特にプログラミング以外の部分で思うようにいかないこともあり作業が進まなかったです

  • 開発時間の確保が一苦労
    今年の初めに第一子が誕生したということもあり、仕事・育児の時間がある中開発時間を確保するのに苦労しました
    主に平日は子を寝かしつけたあと 1 ~ 2時間、休日も隙間時間を使ってちょこちょこ進めていました
    細かくタスクを分解して消化していくことで開発の進捗を感じれるのでモチベーションを保つことができました

  • ネイティブアプリの開発が楽しい
    最近は Web開発ばかりしていたのでネイティブアプリの開発が新鮮に感じました
    開発体験として、クロスプラットフォームで開発できたのも良かったです

思うようにできないことや様々な壁にぶち当たりましたが、ゲーム開発は楽しかったです。
これからは我が子のようにアプリも育てていきたいなと思いました。

もし、興味を持っていただけましたらぜひ遊んでみてください!

2020年12月振り返り

まだ今月は3日残っているが、先月から引き続き今月の振り返り。

エンジニアリング

今月は本業でガッツリコードを書くことが少なかったが Ruby は少し書いた。
Ruby 3.0.0 はまだ触れていないので近々触ってみるつもり。

予定では、今月 Golang をしっかりキャッチアップするつもりだったが、少し前からシステムプログラミングへの興味が強く Ruby をベースに考えると比較的理解も進むかと思ったので「Web で使える mruby システムプログラミング入門」を購入しコツコツ進めている。
実はちょうど先月末に発売されて気になっていた。

この本自体はとても丁寧に解説されているが、序盤はサクサク進めることができて中盤ぐらいからやや難しく感じている。
単純にふわっと理解して写経しつつ進めるなら何ら問題ないが、しっかり理解して進めるとなるとある程度のC言語力が求められる気がする。
そもそも自分のC言語力が低すぎるので、別のアプローチでC言語力を鍛えながら進めていこうと考えた。

ただ、C言語単体で勉強を進めるのはあまり気が進まず、目的のシステムプログラミングを学びつつC言語の基礎を学べるというようにしたかったので、もっと内容が優しそうな「ふつうの Linux プログラミング 第2版」も並行して進めることにした。

今のところ 1/3 ほど読み進めているが、内容もさらに優しく丁寧なのでサクサク進むことができ、C言語に関しても読む前と比べて多少は基礎的なことを理解できている気もする。

そんな感じで、年末年始の宿題としてこの2冊を一通りやり遂げたい。

最近読んだ & 読んでいる本

読んだ本

読んでいる本

興味があることが多すぎて全部中途半端になっているのでなんとかしたい。
あとは最近プログラミング以外の本を読めていない、、、

日常

買った物

  • iPad Pro 11インチ 第二世代 256GB
  • Apple Pencil2

まだあまり使いこなせていないが Kindle を読む時やメモや図を描くのに便利そうだったので買ってみた。
端末自体は軽い方が扱いやすいと思ったので 11インチにしてみたが今のところ不満はない。
容量も 256GB あれば十分な気もする。
今は GoodNotes5 をよく使っていて Apple Pencil も書きやすくて良い感じがする。

GoodNotes 5

GoodNotes 5

  • Time Base Technology Limited
  • 仕事効率化
  • ¥980
apps.apple.com

その他どうでもいいこと

  • リコール対象が2件もあった
    ニトリ珪藻土マット & サンコーの着るこたつが自主回収対象で両方便利で気に入っていただけに残念だった。
    とりあえず珪藻土マットは買い直して、着るこたつは類似商品がなかったのでファンヒーターを導入した。
  • 車検通した
    愛車の車検の時期だったので車検を通した。
    かなり古い車だがあと2年は頑張ってもらう予定。

12月はこんな感じでそれなりに色々仕込みつつ来年に向けて準備をしている。

2020年11月振り返り

前回の更新は5月なので約半年ぶりになるが、最近特に物忘れもひどく朝食べた物までも平気で忘れてしまうレベルなので、最近やったことを簡単にまとめておく。

これから毎月振り返りしたい気持ちも込めてタイトルは2020年11月振り返りにしてみた。 (まあ次は無いだろう)

エンジニアリング

Dataflow を使ってストリーミングでデータ処理をする仕組みなどを作っていて、Java をメインで書いていることが多かった。
今までは Ruby, Perl, PHP などの動的型付け言語を書くことが多く、静的型付け言語をしっかり書いた経験がなかったので、新たに学べることも多くて面白い。
型の役割や安心感がようやく理解できてきた気がする。

並行して Golang もちょこちょこ書き始めていて、まだ簡単なスクリプトを書いているだけではあるが、直前に Java をキャッチアップしていたこともあり、意外とすんなり手に馴染んできている感じがある。
とはいえ、まだまだ実力不足なので年内にある程度使えるレベルにまで持っていければ良いかなと思う。

インフラ周りでは Terraform を書いたり相変わらず GCP を触っている。

また最近は IDE を使っていたが、RubyMine がバグったり重かったりしたのが辛かったので Vim に戻ったりしていて GoLand が便利すぎたのでまた IDE に戻るということを繰り返している。

その他の取り組みとしては夏ぐらいから、デイリーでチームで勉強会を行なっていて以下の本を輪読していて今も継続中。

  • Clean Architecture (読み終えた)
  • 現場で役立つシステム設計の原則 (読んでいる)

まとめると新しいことにチャレンジはできているが、学んだことに対してのアウトプットが少ないのが反省点。
また、以前に比べてコードリーディングをする時間が減っているので今月は Go のモジュールを中心にやっていきたい。

日常

基本的に外に出掛けたりせず、ずっと家に籠っているので家の中で色々楽しんでいる。

DIY

特に DIY に凝っていて週末になると何かしら家具を新しく作ったり、既存の家具をリメイクしている。

直近でやったのは10年ぐらい前から使っているアルミラックをアイアンペイントで塗装した。
金属に塗装するのは初めてだったが、直接塗ると塗料が付かないので下地としてマルチプライマーを塗ってから塗料を塗るなどした。
結果的に、アイアン調にすることで質感がガラッと変わりヴィンテージ感ある良い仕上がりになって満足している。

物を大切に使い続けるタイプなので、愛着ある物をリメイクすると雰囲気も変わり気分も上がるので良い。

買った物

壁に投影しながら家族で大画面で桃鉄をやって楽しんでいる。
まだ肝心の映画を観れていないので、週末に観たい。

その他

Notion でタスクとかメモとか管理するようにしていて使いやすくて感動している。

そういえば、10月になるが大学1年振りに TOEIC を受けた。
現状のレベルを知りたかったということもあり、ほとんど勉強せずに挑んだが200点ぐらい上がっていた。(元の点数が低すぎ)
次は勉強してチャレンジしようと思い、1月に申し込んだがコロナ禍で抽選制の為落ちてしまった。

最近読んだ & 読んでいる本

読んだ本

  • Clean Architecture
  • Software Design 12月号
  • Au オードリー・タン 天才IT相7つの顔
  • 砂糖の世界史
  • The Albert Einstein Story
  • 英語耳

読んでいる本

まだまだ書きたいことが盛り沢山だが、あまり気合入れると次回が辛いのでこの辺で終わり。