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
むろん、原子力発電所で過酷事故が発生したときのような影響範囲の巨大さはそうそうあるものではないと思う。よって、前述の提言が自分の関わるシステムやプロジェクトにそのまま適用できるものではない。しかし、こういったことを常に意識し・目指す姿勢を持つ / 持たないとでは、出来あがるプロセスや組織、そしてシステムもまるで違うものになる。ソフトウェア開発に何年も携わってきたが、あながち外れてはいないんじゃないだろうか。
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
「シンタックス・ハイライト機能で対応してほしい言語」と聞いて真っ先に PowerShell が浮かんだ
PowerShell は言わずと知れた Microsoft 謹製のシェルスクリプティング言語ですが、残念なことにシンタックス・ハイライト機能に対応していません。 自分の周りでは Windows の CLI, シェルスクリプティングといえばいまだにバッチファイルや WSH といったイメージがありますが、PowerShell とて Windows 7 (2009年登場。もう7年前) 以降は標準搭載ですし、はてなさんもそろそろ対応くるんじゃないかなーと期待しています。
PowerShell 未対応の現状
PowerShell 書くときは GitHub に書いてリンクしたり http://alexgorbatchev.com/SyntaxHighlighter/ 使う人が多いみたいですね。
とても同感なエントリ
Java で文字列を16進ダンプする方法
ときどき使うけど覚えていられないメモ。
だいたいはコレで OK
String str = "ジャバ"; // EUC-JP for (byte aByte : str.getBytes("EUC-JP")) { System.out.printf("%2X", aByte); } // A5B8A5E3A5D0
String str = "ジャバ"; // Shift_JIS for (byte aByte : str.getBytes("Shift_JIS")) { System.out.printf("%2X", aByte); } // 83578383836F
こういうのも
String str = "ジャバ"; for (int i = 0; i < str.length(); i++) { String hex = Integer.toHexString(str.charAt(i)); System.out.print(hex.toUpperCase()); } // 30B830E330D0
なぜか周囲は ASCII どころか JIS X 0208 まるごと覚えているような人が珍しくない。
*1:UTF-16BE
Rhino で JavaScript の予約語と同じ名前をもつメソッドを呼び出す方法
Rhino の jrunscript で File#delete() が動かなかった時のメモ *1
起きたこと
File#delete() メソッドを呼ぶとエラーになる。delete は JavaScript の予約語だからダメってことらしい → https://bugzilla.mozilla.org/show_bug.cgi?id=229895
> jrunscript js> new java.io.File('C:\\Users\\shrimp\\hoge.txt').delete(); script error: sun.org.mozilla.javascript.internal.EvaluatorException: missing name after . operator (<STDIN>#1) in <STDIN> at line number 1
JavaScript の予約語ということで typeof を試したけどダメ。他の予約語もダメ。
package hoge; public class JSRW { public void hoge() { System.out.println("hoge"); } public void typeof() { System.out.println("typeof"); } }
$ jrunscript -q Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2 $ jrunscript -cp . js> var jsrw = new Packages.hoge.JSRW(); js> jsrw.hoge(); hoge js> jsrw.typeof(); script error: sun.org.mozilla.javascript.internal.EvaluatorException: missing name after . operator (<STDIN>#1) in <STDIN> at line number 1
解決策
ブラケット表記なら OK.
> jrunscript
js> new java.io.File('C:\\Users\\shrimp\\hoge.txt')['delete']();
true
少し気になったこと
https://bugzilla.mozilla.org/show_bug.cgi?id=229895 では「1.5R5 で直るよー」みたいに書かれてるけど、1.6 でも直ってない?
> C:\Program Files\Java\jdk1.6.0_45\bin\jrunscript.exe -q Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2
Nashorn はちゃんと動く
> C:\Program Files\Java\jdk1.8.0_77\bin\jrunscript.exe -q Language ECMAScript ECMA - 262 Edition 5.1 implementation "Oracle Nashorn" 1.8.0_77 > C:\Program Files\Java\jdk1.8.0_77\bin\jrunscript.exe nashorn> new java.io.File('C:\\Users\\shrimp\\hoge.txt').delete(); true
*1:Ant で allbutlast リソースコレクションを使いたかったのだけどバージョンが古くてが使えず、taskdef タスクで JavaScript 書いたのが元ネタ