日々常々

ふつうのプログラマがあたりまえにしたいこと。

Macで⌘Qでうっかり閉じたくない

AWSでWindowsServerを使う場合とか、WindowsをRemoteDesktopで操作します。

Microsoft Remote Desktop

Microsoft Remote Desktop

apps.apple.com

評価は酷いものだけど、他にあるかどうかも良し悪しもよくわからないし、動けば良いやって気分なのでこれ。

こう言うので全画面表示で操作してると、うっかり⌘Q(WindowsではAlt+F4相当)でウィンドウを閉じようとするんですよね。 そしたらRemoteDesktopさんがお亡くなりになる……

f:id:irof:20200701140154p:plain

眠いと頻発します。

AM3時くらいに閉じまくって不貞腐れて寝たんですが、ちゃんと寝たんで3分くらいで解決しました。

f:id:irof:20200701140337p:plain

Macそこそこ長いこと使ってるんですがいまいち使いこなせてない メニューの表示文言と一致したもののショートカットを設定する機能 (と私が認識しているもの)です。 もともとショートカットが割り当てられていたら上書きされます。

これ便利なんですが、「メニューの表示文言」なので、アプリによってメニューが微妙に違う(翻訳されてたり)と合わないんですよね。 一方で「メニューの表示文言」なので、アプリケーションを問わずに設定できるのはパワフル。

アプリケーション固有の設定をOSにするのに微妙に違和感があったり、「ショートカットを変えたい」に対する直接的な解決ではない(結果的には変わってるんだけど)あたりが、なかなかなんと言うか。

OSの機能なので常識と言っても良いかもなんだけど、知らない人も多分多いと思う。私みたいな雰囲気でMac使ってる人は特にそうだと思う。 Macを最初に買ったのは2011年7月っぽい(当時のTwitter)から9年になるわけど、いまだに雰囲気と言うかOSの機能はよくわかってない……

別解

ツイートしたらリプで教えてもらいました。

Chromeとか⌘Qを押すと「ほんとに閉じんの?」なダイアログが表示されるのは皆さんご存知かと思うんですが、全部そんな感じにするものっぽいです。 お好みで。

「ソースコードブランチ管理のパターン」のダイアグラム

お世話になっている人も多い Martin Fowler's Blikiの日本語翻訳サイト 、いつも運営&翻訳ありがとうございます。

パターン言語は関連が重要な役割を担っています。そして関連はダイアグラムにすると捗ります。ダイアグラムがついている書籍もよくみます。 なので、ダイアグラムがないときや書籍と違う雰囲気のダイアグラムが欲しくなった場合、自分で描きながら読んでたりします。こんな感じで。

f:id:irof:20200619003635p:plain

紙に手書きすることも多いのですが、インターネットで公開されているものはURLが付けやすいのでSVGで作るのが最近のマイブーム。SVGはサイズが大きくなっても拡大すれば読めるのでいいです。 上の画像はPNGをアップロードしたものなのでGistに上げました。 GistのSVGへのリンクを置いておきます。Gistのページだと画像は表示してくれるんだけど、結局URLがリンクにならないので。

ブラウザで開いて各ノードをクリックしてみてください。便利ですよね?Gistのリンクにしているのは、はてなブログの画像にSVGが使えないから。SVGだから仕方ない。 あとimgタグで入れてないのも、imgタグ内のSVGはURLがリンクになってくれないから……。

ブラウザで画像として見れるSVGですが、SlackやTwitterに投稿しても画像になってくれなくて、たまに悲しい気分になります。

機械的に作るだけならHTMLやMarkDownから生成もできるのだけど、心温まる手作業で書いています。 エッジを追加しながら「あーここがつながるのねー」とかグラフの変化を楽しみながら読んだりします。ある種の写経ですね。

ちなみにソースは以下の通り。Gistにもあげたんだけど、そうすると画像よりもこっちが上にきて微妙だったのでやっぱ消した。

digraph {
node[shape=box, style=filled]

subgraph ベースパターン {
    label=ベースパターン
    node[fillcolor=lightyellow]

    ソースブランチング[URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%83%B3%E3%82%B0-"]
    メインライン[URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3-"]
    健全なブランチ[URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E5%81%A5%E5%85%A8%E3%81%AA%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
}

subgraph インテグレーションパターン {
    label=インテグレーションパターン
    node[fillcolor=lightgreen]

    メインラインインテグレーション [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-"]
    フィーチャーブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    継続的インテグレーション [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-"]
    レビュー済みコミット [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E6%B8%88%E3%81%BF%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88-"]
}

subgraph メインラインから本番リリースへの道のり {
    label=インラインから本番リリースへの道のり
    node[fillcolor=lightblue]

    リリースブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    成熟度ブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E6%88%90%E7%86%9F%E5%BA%A6%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    環境ブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E7%92%B0%E5%A2%83%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    ホットフィックスブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%9B%E3%83%83%E3%83%88%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    リリーストレイン [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%88%E3%83%AC%E3%82%A4%E3%83%B3-"]
    リリース可能なメインライン [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E5%8F%AF%E8%83%BD%E3%81%AA%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3-"]
}

subgraph その他のブランチパターン {
    label=その他のブランチパターン
    node[fillcolor=pink]

    実験的ブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E5%AE%9F%E9%A8%93%E7%9A%84%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    未来ブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E6%9C%AA%E6%9D%A5%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    コラボレーションブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%82%B3%E3%83%A9%E3%83%9C%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
    チームインテグレーションブランチ [URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#-%E3%83%81%E3%83%BC%E3%83%A0%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81-"]
}

メインライン -> メインラインインテグレーション
メインライン -> リリースブランチ
メインライン -> リリーストレイン

健全なブランチ -> メインライン
健全なブランチ -> レビュー済みコミット
健全なブランチ -> メインラインインテグレーション

メインラインインテグレーション -> レビュー済みコミット
メインラインインテグレーション -> コラボレーションブランチ

フィーチャーブランチ -> 継続的インテグレーション

レビュー済みコミット -> メインラインインテグレーション
レビュー済みコミット -> フィーチャーブランチ
レビュー済みコミット -> 継続的インテグレーション

リリースブランチ -> 環境ブランチ
リリースブランチ -> 成熟度ブランチ

環境ブランチ -> 成熟度ブランチ

リリーストレイン -> リリースブランチ
リリーストレイン -> フィーチャーブランチ
リリーストレイン -> リリース可能なメインライン
リリーストレイン -> 継続的インテグレーション

リリース可能なメインライン -> メインライン
リリース可能なメインライン -> 健全なブランチ
リリース可能なメインライン -> 継続的インテグレーション
リリース可能なメインライン -> フィーチャーブランチ
リリース可能なメインライン -> リリースブランチ

コラボレーションブランチ -> メインライン
コラボレーションブランチ -> メインラインインテグレーション
コラボレーションブランチ -> 継続的インテグレーション
コラボレーションブランチ -> 実験的ブランチ

チームインテグレーションブランチ -> 健全なブランチ

/*
subgraph ブランチポリシー {
    label=ブランチポリシー

    "Git-flow"[URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#git-flow"]
    "GitHub Flow"[URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#github-flow"]
    トランクベース開発[URL="https://bliki-ja.github.io/PatternsForManagingSourceCodeBranches/#%E3%83%88%E3%83%A9%E3%83%B3%E3%82%AF%E3%83%99%E3%83%BC%E3%82%B9%E9%96%8B%E7%99%BA"]
}

"Git-flow" -> メインライン
"Git-flow" -> フィーチャーブランチ
"Git-flow" -> コラボレーションブランチ
"Git-flow" -> 成熟度ブランチ
"Git-flow" -> リリースブランチ
"Git-flow" -> ホットフィックスブランチ
"Git-flow" -> 健全なブランチ
"Git-flow" -> リリース可能なメインライン

"GitHub Flow" -> リリース可能なメインライン
"GitHub Flow" -> リリースブランチ[style=dotted]
"GitHub Flow" -> ホットフィックスブランチ[style=dotted]
"GitHub Flow" -> フィーチャーブランチ
"GitHub Flow" -> メインラインインテグレーション
"GitHub Flow" -> レビュー済みコミット

トランクベース開発 -> メインライン
トランクベース開発 -> メインラインインテグレーション
トランクベース開発 -> フィーチャーブランチ
トランクベース開発 -> 継続的インテグレーション
トランクベース開発 -> リリースブランチ
トランクベース開発 -> リリース可能なメインライン
*/
}

Graphvizに食べさせてSVGPNGで出力できます。雑なコマンドだと dot -Tpng -O hoge.gv って感じで hoge.gv.png ができる。とはいえリアルタイムプレビューが欲しいので、VS CodeでExtension使うほうが多いのだけど。ファイルの拡張子は *.dot*.gv で、最近はなんとなく後者を使うことにしてます。

元記事で紹介されている書籍の「パターンによるソフトウェア構成管理」は、やはり整理にいいよなぁと改めて思いました。

以前脱ブランチファーストで触れたものです。追加で何かしら書きたいと思ったりしてる今日この頃。そんなことばっかり言ってるなぁ……。

IDEに何を期待してどう使おうか

先日オンラインで行われたJJUGJava生誕25周年 記念イベント 5/23(土) 開催で話させていただきました。

Java25周年おめでとうございますですね。もうJavaより若い開発者さんも結構おられることでしょう。これ会場で「Javaより若い人ー」とかやったら、結果がどっちでも微妙な空気になりそうですね。オフラインだとうっかりやっちゃった気がしないでもないので、オンラインでよかった!

さて、タイトルは「IDE起点で2020年代の開発環境を眺めてみる」です。

スライド

動画もあったりする。自分の動画ってあまりみたくない

話したつもりのこと

(……を書いてるつもりだけれど、話してないことも混じってるかもしれない。)

一口に「Javaを使ったアプリケーションの開発環境」と言っても、実際は様々な道具を使用します。 とは言え、我々開発者の仕事は「道具をうまく使う」ではありません。 道具なんてどうでもいいのです。「どうでもいい」と言うには、道具に意識が向いていては言えません。手足のように使えないと、どうでもよくならないのです。

自然体で使えるようにするために道具を知る必要があります。 その道具が何者で、何を期待してよくて、何を期待すべきでない、何をさせてはいけないのか……この関係性を記号化するとモデルが描けます。私の認識が資料の29,31ページ。

この関係性においてIDEに何を期待するか。開発者にべったり寄ることです。コンピュータとうまくやるところはIDEの先の道具に任せてしまって、私の開発を全力で手助けしてくれることがIDEに期待することです。 特に開発時しか要らないことはIDEが受け持つべきで、ビルドツールやバージョン管理が持つとおかしなことになります。

また、一つの役割を複数の道具で担わせるのはよくありません。原本が一つで伝播するならまだ良いですが、複数原本がある状態になると収拾がつかなくなります。

依存方向が交錯する例は37ページで挙げています。

図があまりよろしくない……シーケンシャルに見える。上と下の2パターンありますよね、と。実物の例してはMavenEclipseプラグインと、EclipseMavenプラグイン。他の組み合わせでも大体あります。

この連携をするとビルドツールとIDEに関連ができます。そして今時は必ず連携するでしょう。 どちらの方向にするかを考える時に、先の「開発のモデル」を参照してみてください。 ビルドツール→IDEの依存を作ると、ビルドサーバーからIDEまで依存が辿れてしまいます。 実際は設定ファイルで分離されるためそこまで強固な結合ではないのですが、依存方向として許してしまうと、あれもこれもと乗りがちです。 下手をすれば「CI環境にIDEがインストールされていないとビルドできない」なんてことになりかねません。

「開発のモデル」の要点はIDEへの依存がないことです。IDEの独立を維持できると、IDEの設定は個人に特化できます。 多人数開発において開発環境の統一はそれなりに効果はありますが、どうしても個々人の最大限のパフォーマンスからは目減りします。

私は常駐の支給端末で開発していたことも多く、プロジェクトが変わるたびに端末から入れ替えとかだったので、あまりIDEのカスタマイズはしない派でした。 キーマップも変えず何もかもデフォルトで使うのが、当時の私にとって最大のパフォーマンスが発揮できる道具の使い方だったからです。 今もあまり思い切ったことはしていませんが、ちょいちょいカスタマイズはしています。

IDEがないと開発が一切できない」なんてことはありません。ですが、IDEを自分のためだけのものと位置付けて手に馴染ませられれば、効率は非常に上がります。 そのためにはIDEは他から依存されてはいけないですし、IDEが独立を保てるならいくらでもカスタマイズできます。

で、Javaの世界では、外から依存されるべきでないIDEがいまだに握っちゃってる問題がフォーマッタなんだよねぇ……。

フォーマッタについては過去の私(2012年)に何か思うことがあったらしいです。

irof.hateblo.jp irof.hateblo.jp

goとか見てると、フォーマッタは言語が持ってくれるのがいいなぁと思ったりしてます。 今更言語が持つのは厳しいでしょうから、とりあえずIDEから独立して使える別ツールになってくれたりしないかなぁ、とか。 コード管理システムのhookやCIで回すのもやってみたけど、今のところしっくり来てません。IntelliJのフォーマットをコマンドラインで動かせはするんだけど、動かせはする、くらいでコレジャナイだった。 コードとフォーマットについてはそのうちまた別口で書きます。覚えてたら。こう書いて覚えてたことってあるんだろうか私……。

オンラインセッションをやってみて

初のきっちりしたオンラインセッションでしたが、難しいですね。 私は話しながら聞いてくれてる人の反応を見つつ、話を足したり削ったりするのですが、そういうのができないセッションも新鮮でした。 オンラインの勉強会はきっと今後もあると思うので、何かしらオンラインならではのを仕掛けたいですね。

その一環としてCommentScreenを使って字幕を流していました。今でも動画でみれるかと思います。 Twitter連携してハッシュタグが流せます。Twitterなくても専用のフォームがありますが、今回はTwitter連携だけで。 YouTube Liveだったので数十秒の遅延があって、リアルタイムに反応を拾う目的でやったのですがこれは外しました。最初から分かってはいましたが、数秒ならともかく数十秒はキツイ。 でもなんの反応もないよりはやりやすかったです。