全力で怠けたい

怠けるために全力を尽くしたいブログ。

IntelliJ IDEA + Lombok + Gradle の環境構築メモ

IntelliJ IDEA で Lombok を使う環境を作り直した時のメモ。

やったこと

  • SDKMAN! のインストール
  • Gradle のインストール
  • build.gradle に依存関係を記述
  • Lombok Plugin のインストール
  • Annotation Processors の設定

SDKMAN! のインストール

homebrew で Gradle を管理していたのを SDKMAN! (旧 GVM) で管理するように変更。

公式サイト に書いてあるコマンドを打つだけで完了。

$ curl -s https://get.sdkman.io | bash

# 省略

$ source "$HOME/.sdkman/bin/sdkman-init.sh"

SDKMAN! をインストールすると .zshrc (or .bashrc) に SDKMAN! 用の設定が追加される。

#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
export SDKMAN_DIR="/Users/shrimp/.sdkman"
[[ -s "/Users/shrimp/.sdkman/bin/sdkman-init.sh" ]] && source "/Users/shrimp/.sdkman/bin/sdkman-init.sh"

Gradle のインストール

こちらも公式サイトに書いてあるコマンドを打つだけで完了。
途中で Gradle 3.2 をデフォルトにしてもいいか聞いてくるので、デフォルトにするなら y を入力する。

$ sdk install gradle 3.2

Downloading: gradle 3.2

In progress...

######################################################################## 100.0%

Installing: gradle 3.2
Done installing!

Do you want gradle 3.2 to be set as default? (Y/n): y

Setting gradle 3.2 as default.

build.gradle に依存関係を記述

build.gradle に以下を記述。

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compileOnly "org.projectlombok:lombok:1.16.10"
}

Lombok Plugin のインストール

f:id:ebc_2in2crc:20161119171335p:plain

Preferences - Plugins から「Lombok Plugin」をインストールする。

f:id:ebc_2in2crc:20161119164341p:plain

インストールを反映するために IntelliJ を再起動するか聞いてくるので「Restart」を選択して再起動する。

Annotation Processors の設定

f:id:ebc_2in2crc:20161119164327p:plain

Preferences - Build, Execution, Deployment - Compiler - Annotation Processors から「Enable annotation processing」にチェックする。

以上。

システム間接続のはまりパターン

中〜大規模開発のシステム間接続でハマったときのメモ。

連携方法は様々だが 徹底解説! ITアーキテクトとは何か?(4):システム間連携のアーキテクチャ、4つの基本パターンと正しい適用のポイント (1/2) - @IT で解説されているアプリケーション連携が多い。

LAN アナライザーを使えばすぐ分かりそうなものが大半だが、禁止されている現場が多いのかもしれない。

接続できません!どうなってるんですか!?

ステルス接続

こちらのログには出力なし。LAN アナライザーでもパケットを拾えない。

原因は…

  • 相手の設定が間違っていてテスト環境を向いていた
  • ネットワーク経路で止められていた (ルータ、プロキシーなど)
  • 相手のマシンがテスト環境のマシンだった

404 not found

URL が間違っている。

原因は相手の設定ミスなのだが「こちらはすぐに直せないのでそちらでなんとかしてください!」…ここでなんとかするのも仕事である。

応答がありません!

"接続できない" から一歩前進。

原因は…

  • こちらからはちゃんと応答しているのだが、受信した相手プロセス (スレッド) がなぜか死ぬ
  • 上記同様だが、相手プロセスが無限ループで無応答に見える

エラーが返ってくるんですが!どうなってるんですか!?

原因のほとんどは「エラーを返すのが正しい」パターン。

  • プロトコル違反: たいがいがアプリケーションプロトコル違反
  • プロトコル違反ではないが、HTTP ヘッダに "Connection: Close" を指定しておいて 同じ TCP 接続で再度 POST してくるなんていうのも
  • 相手の設定が間違っていてテスト環境を向いていた (これもよくある)

データが送られてこないんですが!

原因は…

  • こちらからはちゃんと送っているのだが、受信した相手プロセス (スレッド) がなぜか死ぬ
  • 上記同様だが、相手プロセスが無限ループで無応答に見える
  • 上記同様だが、相手の処理が遅すぎてタイムアウト

変わり種: そちらのデータを受信すると CPU 100% になるんですが!

ビジー無限ループ (送ったデータは正しかった)

学んだこと

システム開発ではすべてを疑え *1

*1:まず自分の書いたプログラムを疑うのは大前提

Mercurial 作業領域の状態をいい感じに表示する PowerShell プロンプト

C:\Users\shrimp [hg: default +]
PS>

# Mercurial リポジトリにいると "[hg: <ブランチ名>]" のように表示してくれる
# 作業領域にコミットしていない変更がある場合は ブランチ名の後ろに "+" も表示

こんな感じに表示してくれる。

function Prompt {
  $HgBranch = hg branch 2> $null
  if ($HgBranch -ne $null) {
    if ((hg st 2> $null | where { $_ -match '^[MAR!] ' } | measure).Count -gt 0) {
      $HgBranch = "$hgBranch +"
    }
    $HgBranch = "[hg: $hgBranch]"
  }

  Write-Host -NoNewLine -ForegroundColor DarkGray "$(pwd)"
  Write-Host -ForegroundColor Yellow " $HgBranch"
}

こんな感じの Prompt 関数を $env:userprofile の Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 に保存しておくと PowerShell の起動時に勝手に読み込んでくれるので楽。

プロンプトの表示タイミングでしか変更をチェックしないのがちょっと残念だけどまずまず便利に使ってる。

"形を作っただけでは機能しない。仕組みは作れるが、目的は共有されない" ソフトウェア開発の現場も同じ

縁あって福島第一原子力発電所の事故についての 政府事故調査報告書 を読んだ。

非常にボリュームがあるので流し読みしただけだが、最後の総括と提言には非常に考えさせられたのでメモ。

(1)あり得ることは起こる。あり得ないと思うことも起こる。
(2)見たくないものは見えない。見たいものが見える。
(3)可能な限りの想定と十分な準備をする。
(4)形を作っただけでは機能しない。仕組みは作れるが、目的は共有されない。
(5)全ては変わるのであり、変化に柔軟に対応する。
(6)危険の存在を認め、危険に正対して議論できる文化を作る。
(7)自分の目で見て自分の頭で考え、判断・行動することが重要であることを認識し、そのような能力を涵養することが重要である。

形を作っただけでは機能しない

特に考えさせられ・共感したのが "(4)形を作っただけでは機能しない。仕組みは作れるが、目的は共有されない。" だ。短いので全文を引用する。

(4)形を作っただけでは機能しない。仕組みは作れるが、目的は共有されない。
事業者も規制関係機関も地方自治体も、それぞれの組織が形式的には原発事故に対
応する仕組みを作っていた。しかし、いざ事故が起こるとその対応には不備が散見さ
れた。それは組織の構成員がその仕組みが何を目的とし、社会から何を預託されてい
るかについて十分自覚していなかったためと考えられる。各構成員が何をしなければ
いけないかを自分の問題として自覚している状態を作らなければ、仕組みを作っても
全体としては機能しない。目的が共有されないからである。緊急時のために構築され
SPEEDI のシステムが避難に活用されなかったのは正にこの例である。
構成員全員が目的を共有するには、それぞれが社会から何を預託され、自分が全体
の中でどこにいるのか、また自分の働きが全体にどのような影響を与えるかを常に考
えているような状態を作らなければならない。その状態を更に維持するためには教育
と訓練が必要である。社会がそれぞれの構成員に預託している事柄をきっちり自覚で
きるような社会運営をしなければならない。

特にこのあたり。

  1. 事故に対応する仕組みを作っていたが、実際の事故時には不備が散見された
  2. 自分の問題として自覚していなければ、仕組みを作っても機能しない
  3. 自分が全体の中でどこにいるのか、自分の働きが全体にどう影響するのか
  4. その状態を維持するためには教育と訓練が必要

これはソフトウェア開発や保守の現場で常に議論され、考えさせられることとまったく同じだ。人気のビルドツールを使ったからといってビルドが上手くいくとは限らないし、最新の言語を使ったからといってシステムの質が向上するとも限らない。もっと大きな枠で見ても、ウォーターフォールで開発したからといってプロジェクトが失敗するとは限らないし、アジャイルで開発したからといってプロジェクトが成功するとも限らない。なぜなら、ツールやプラクティスといったものは箱モノではないからだ。だから、導入しただけでその価値を得られることなどそうそうない *1

まとめ

使えば使うほど・習熟すればするほど "お得になる"、それがツールやプラクティスだと思う。もちろん、ここでの習熟には使うべきではないところの見極めなども含まれるのはいうまでもない *2

むろん、原子力発電所で過酷事故が発生したときのような影響範囲の巨大さはそうそうあるものではないと思う。よって、前述の提言が自分の関わるシステムやプロジェクトにそのまま適用できるものではない。しかし、こういったことを常に意識し・目指す姿勢を持つ / 持たないとでは、出来あがるプロセスや組織、そしてシステムもまるで違うものになる。ソフトウェア開発に何年も携わってきたが、あながち外れてはいないんじゃないだろうか。

*1:個人的にはうま味という言葉がしっくりくる

*2:たかだか300行のプログラムに GOF デザインパターンを10個も適用したらと考えたらゾッとする

TortoiseHg で一手間省いてコミットメッセージやリビジョンハッシュをコピーする方法

f:id:ebc_2in2crc:20160614231039j:plain

TortoiseHg のリビジョングラフにはコミットメッセージやリビジョンハッシュなど好きな列を表示できる。この列をクリックして Command + C するとその列の内容がクリップボードにコピーされる。メールや IM に貼り付けるときに大変重宝している *1

*1:Mac 版と Windows 版の TortoiseHg 3.8.3 で確認したけど多分もっと古いバージョンでもできると思う

Mercurial のキーワード拡張を使うと改名が追跡されない問題の対応方法

Mercurial でバージョン管理しているファイルを Mercurial を通さずに改名したときに変更前ファイルが追跡できなかったときのメモ *1

普通は追跡できる

[shrimp]$ hg init hoge; cd hoge

# 適当にファイルを作ってコミット
[shrimp]$ echo 'hoge' > a.txt
[shrimp]$ hg add
adding a.txt
[shrimp]$ hg commit -m "add a.txt"

# Mercurial を通さずにファイル名を変更
[shrimp]$ mv a.txt b.txt

# 変更前ファイルの削除と変更後ファイルを登録してコミット
[shrimp]$ hg addremove
adding b.txt
removing a.txt
[shrimp]$ hg commit -m "a.txt rename to b.txt"

# b.txt の変更履歴を見る
# 改名前の a.txt を作成したリビジョン0も出力される
[shrimp]$ hg log --follow --template '{rev} {desc}\n' b.txt
1 a.txt rename to b.txt
0 add a.txt

キーワード拡張を使うと追跡できない

キーワード拡張の設定はこんな感じ。

[shrimp]$ cat .hg/hgrc
[extensions]
keyword =

[keyword]
**.txt =

[keywordmaps]
Header = {file|basename} {node|short}

こうしておいてファイルの中に $Header$ と書いておくと $Header: a.txt 714c62379545 $ みたいに展開してくれるのだが、こうしておいて先ほどと同じようにしても今度はファイル名変更前の a.txt を作成したリビジョン0 が出力されない。

[shrimp]$ hg init fuga; cd fuga

# ./.hg/hgrc にキーワード拡張を設定

# 適当にファイルを作ってコミット
[shrimp]$ echo '$Header$
ほげほげ' > a.txt
[shrimp]$ hg add
adding a.txt
[shrimp]$ hg commit -m "add a.txt"

# Mercurial を通さずにファイル名を変更
[shrimp]$ mv a.txt b.txt

# 変更前ファイルの削除と変更後ファイルを登録してコミット
[shrimp]$ hg addremove
adding b.txt
removing a.txt
[shrimp]$ hg commit -m "a.txt rename to b.txt"

# b.txt の変更履歴を見る
# 改名前の a.txt を作成したリビジョン0が出力されない
[shrimp]$ hg log --follow --template '{rev} {desc}\n' b.txt
1 a.txt rename to b.txt

解決方法

addremove するときに --similarity オプションを指定すればいい。

[shrimp]$ hg init piyo; cd piyo

# ./.hg/hgrc にキーワード拡張を設定

# 適当にファイルを作ってコミット
[shrimp]$ echo '$Header$
ほげほげ' > a.txt
[shrimp]$ hg add
adding a.txt
[shrimp]$ hg commit -m "add a.txt"

# Mercurial を通さずにファイル名を変更
[shrimp]$ mv a.txt b.txt

# 変更前ファイルの削除と変更後ファイルを登録してコミット
# このとき --similarity オプションを指定する
[shrimp]$ hg addremove --similarity 1
adding b.txt
removing a.txt
recording removal of a.txt as rename to b.txt (37% similar)
[shrimp]$ hg commit -m "a.txt rename to b.txt"

# b.txt の変更履歴を見る
# 改名前の a.txt を作成したリビジョン0も出力される
[shrimp]$ hg log --follow --template '{rev} {desc}\n' b.txt
1 a.txt rename to b.txt
0 add a.txt

まとめ

--similarity オプションは、ファイルの類似度をパーセンテージで指定して改名検知するためのオプション。指定しない場合は100が指定されたものとみなされて、完全一致するファイルのみが改名とみなされる。キーワード拡張を使っているときに Mercurial を通さずに改名するとキーワード部分が一致しないため改名検知されない。しかし、リファクタリングで改名した場合などはそれが明らかであるから、--similarity オプションで意図的に類似度を下げて Mercurial に改名を検知させればいい *2

IntelliJ IDEA は大丈夫

IntelliJ IDEA + hg4Idea の場合は IntelliJリファクタリング機能で改名しても、ちゃんと hg log --follow で改名前のファイルが出力される。便利。

*1:IDEリファクタリング機能でディレクトリを移動しまくった

*2:--similarity オプションに0を指定すると改名を一切検知しなくなるので注意

「シンタックス・ハイライト機能で対応してほしい言語」と聞いて真っ先に PowerShell が浮かんだ

お題「シンタックス・ハイライト機能で対応してほしい言語」

PowerShell は言わずと知れた Microsoft 謹製のシェルスクリプティング言語ですが、残念なことにシンタックス・ハイライト機能に対応していません。 自分の周りでは WindowsCLI, シェルスクリプティングといえばいまだにバッチファイルや WSH といったイメージがありますが、PowerShell とて Windows 7 (2009年登場。もう7年前) 以降は標準搭載ですし、はてなさんもそろそろ対応くるんじゃないかなーと期待しています。

PowerShell 未対応の現状

PowerShell 書くときは GitHub に書いてリンクしたり http://alexgorbatchev.com/SyntaxHighlighter/ 使う人が多いみたいですね。

とても同感なエントリ

matarillo.hateblo.jp