[インデックス 17487] ファイルの概要
このコミットは、Goプロジェクトのコードレビューツール codereview.py
における、Mercurial 2.7への対応に関する変更です。具体的には、Mercurialの promptchoice
関数の使用方法がバージョン2.7で変更されたことに伴い、既存のコードが正しく動作するように修正されています。
コミット
commit 8f764fb689ea4313c5a6de2cabdf65aee9f89c5d
Author: Anthony Martin <ality@pbrane.org>
Date: Fri Sep 6 15:48:21 2013 -0400
codereview: update use of promptchoice for Mercurial 2.7
Fixes #6186.
R=golang-dev, bradfitz, remyoudompheng, rsc
CC=golang-dev
https://golang.org/cl/13112043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8f764fb689ea4313c5a6de2cabdf65aee9f89c5d
元コミット内容
codereview: update use of promptchoice for Mercurial 2.7
Fixes #6186.
R=golang-dev, bradfitz, remyoudompheng, rsc
CC=golang-dev
https://golang.org/cl/13112043
変更の背景
この変更は、Goプロジェクトのコードレビューシステムが依存しているバージョン管理システムであるMercurialのバージョン2.7における変更に対応するために行われました。Mercurial 2.7では、対話型プロンプトを表示するための promptchoice
関数の引数形式が変更されました。
Goプロジェクトでは、コードレビュープロセスを自動化・効率化するために codereview.py
というPythonスクリプトを使用しています。このスクリプトは、Mercurialコマンドを内部的に呼び出し、ユーザーからの入力を promptchoice
のようなMercurialのUI関数を通じて受け取っていました。Mercurial 2.7へのアップグレードにより、promptchoice
の呼び出し方が古くなり、スクリプトが正しく動作しなくなる問題が発生しました。
コミットメッセージにある Fixes #6186
は、この変更がGoプロジェクトのIssueトラッカーで報告されたバグ #6186 を修正するものであることを示しています。このバグは、Mercurial 2.7環境でコードレビューツールが機能しないという問題であったと推測されます。
前提知識の解説
Mercurial (Hg)
Mercurialは、分散型バージョン管理システム(DVCS)の一つです。Gitと同様に、各開発者がコードベースの完全な履歴をローカルに持ち、オフラインでの作業やブランチの作成・マージが容易に行えます。Goプロジェクトは、初期にはMercurialを主要なバージョン管理システムとして利用していました。
promptchoice
関数
Mercurialの内部には、ユーザーとの対話を行うためのUI(ユーザーインターフェース)関数群が存在します。promptchoice
はその一つで、ユーザーに複数の選択肢を提示し、その中から一つを選ばせるための関数です。例えば、「変更をコミットしますか? (y/n)」といった質問に対して、ユーザーが y
または n
を入力するようなシナリオで利用されます。
codereview.py
codereview.py
は、Goプロジェクトが独自に開発したコードレビュー支援ツールです。このツールは、Mercurialリポジトリと連携し、変更セットの作成、レビューサーバーへのアップロード、レビューコメントの取得、変更の適用など、コードレビューワークフローを効率化するための機能を提供していました。Pythonで書かれており、MercurialのPython APIを利用してMercurialの操作を行っていました。
バージョン管理システムの互換性問題
ソフトウェア開発において、依存するライブラリやツールのバージョンアップは頻繁に発生します。これらのバージョンアップには、APIの変更や非推奨化が含まれることがあり、それによって既存のコードが動作しなくなる「互換性問題」が発生することがあります。本コミットは、まさにMercurialのAPI変更によって引き起こされた互換性問題に対処する典型的な例です。
技術的詳細
Mercurial 2.7における promptchoice
関数の変更は、その引数形式にありました。以前のバージョンでは、選択肢のリストを直接引数として渡す形式でしたが、Mercurial 2.7からは、メッセージ文字列の中に選択肢を特殊な形式で埋め込む形式に変更されました。
具体的には、Mercurial 2.7以降では、promptchoice
のメッセージ文字列内に $$ &yes $$ &no
のように $$
で囲まれた選択肢を含めることで、ユーザーに提示する選択肢を定義するようになりました。これにより、promptchoice
の呼び出し側は、メッセージと選択肢を単一の文字列として渡すことになります。
この変更は、MercurialのUIレイヤーの内部的な設計変更によるものと考えられます。おそらく、より柔軟なプロンプト表示や、国際化対応などを考慮した結果、このような形式になったと推測されます。
codereview.py
は、MercurialのPython APIを通じて ui.promptchoice
を呼び出していました。Mercurial 2.7へのアップグレード後、codereview.py
が古い引数形式で promptchoice
を呼び出すと、Mercurialはそれを認識できず、エラーとなるか、意図しない動作を引き起こしていました。
このコミットでは、hgversion
という変数を用いてMercurialのバージョンをチェックし、バージョン2.7以上の場合とそれ未満の場合で promptchoice
の呼び出し方を分岐させることで、この互換性問題を解決しています。
コアとなるコードの変更箇所
変更は lib/codereview/codereview.py
ファイルの promptyesno
関数にあります。
--- a/lib/codereview/codereview.py
+++ b/lib/codereview/codereview.py
@@ -712,7 +712,10 @@ Examples:
''''
def promptyesno(ui, msg):
- return ui.promptchoice(msg, ["&yes", "&no"], 0) == 0
+ if hgversion >= "2.7":
+ return ui.promptchoice(msg + " $$ &yes $$ &no", 0) == 0
+ else:
+ return ui.promptchoice(msg, ["&yes", "&no"], 0) == 0
def promptremove(ui, repo, f):
if promptyesno(ui, "hg remove %s (y/n)?" % (f,)):
コアとなるコードの解説
promptyesno
関数は、ユーザーに「はい/いいえ」の選択肢を提示し、その結果をブール値で返すヘルパー関数です。
変更前は、以下のコードでした。
def promptyesno(ui, msg):
return ui.promptchoice(msg, ["&yes", "&no"], 0) == 0
ここでは、ui.promptchoice
に対して、メッセージ msg
と、選択肢のリスト ["&yes", "&no"]
、そしてデフォルトの選択肢のインデックス 0
(つまり "yes") を渡していました。
変更後は、Mercurialのバージョンをチェックする条件分岐が追加されています。
def promptyesno(ui, msg):
if hgversion >= "2.7":
return ui.promptchoice(msg + " $$ &yes $$ &no", 0) == 0
else:
return ui.promptchoice(msg, ["&yes", ["&no"], 0) == 0
if hgversion >= "2.7":
- この条件は、現在実行されているMercurialのバージョンが2.7以上であるかどうかをチェックしています。
hgversion
は、codereview.py
のどこかでMercurialのバージョン情報を取得して設定されているグローバル変数またはモジュール変数であると推測されます。 - バージョンが2.7以上の場合、
ui.promptchoice
の呼び出し方が変更されています。msg + " $$ &yes $$ &no"
: メッセージ文字列msg
の後ろに、新しい形式の選択肢文字列" $$ &yes $$ &no"
を連結しています。これにより、promptchoice
は単一の文字列からメッセージと選択肢の両方を解析するようになります。0
: デフォルトの選択肢のインデックスは引き続き0
です。
- この条件は、現在実行されているMercurialのバージョンが2.7以上であるかどうかをチェックしています。
else:
- Mercurialのバージョンが2.7未満の場合(つまり、古いバージョン)、以前と同じ
ui.promptchoice(msg, ["&yes", "&no"], 0)
の呼び出し方が維持されます。
- Mercurialのバージョンが2.7未満の場合(つまり、古いバージョン)、以前と同じ
この変更により、codereview.py
はMercurialのバージョンに依存せず、異なるバージョンのMercurial環境でも promptyesno
関数が正しく動作するようになりました。これは、後方互換性を維持しつつ、新しいバージョンのMercurialにも対応するための一般的なプログラミングパターンです。
関連リンク
- GoプロジェクトのIssue #6186: https://github.com/golang/go/issues/6186 (このコミットが修正したバグの報告)
- Goプロジェクトのコードレビューツールに関するドキュメント (当時のもの): https://go.dev/doc/contribute#code_reviews (現在のドキュメントはGitベースになっているため、当時のMercurialベースのワークフローとは異なる可能性があります)
- Mercurial公式ドキュメント: https://www.mercurial-scm.org/
参考にした情報源リンク
- Mercurial 2.7 リリースノート (
promptchoice
の変更に関する記述がある可能性): https://www.mercurial-scm.org/wiki/WhatsNew2.7 (当時のリリースノートを確認することで、promptchoice
の具体的な変更内容をより深く理解できます) - MercurialのUIモジュールに関するドキュメント (Python API): https://www.mercurial-scm.org/wiki/PythonApi/ui (当時のAPIドキュメントを参照することで、
promptchoice
の詳細な仕様を確認できます) - Goプロジェクトのコードレビュープロセスに関する歴史的な情報 (当時のワークフローを理解するため): https://go.dev/doc/contribute (現在のドキュメントはGitベースですが、過去のコミット履歴やメーリングリストなどを参照することで、Mercurial時代のワークフローに関する情報を得られる可能性があります)
- Pythonのバージョン互換性に関する一般的な情報: https://docs.python.org/
- 分散型バージョン管理システムに関する一般的な情報: https://ja.wikipedia.org/wiki/%E5%88%86%E6%95%A3%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0
- Goプロジェクトの歴史に関する情報: https://go.dev/blog/ (Goプロジェクトのブログ記事には、バージョン管理システムの移行など、プロジェクトの歴史に関する情報が含まれている場合があります)