[インデックス 17330] ファイルの概要
このコミットは、Go言語のEmacsモード(go-mode.el
)において、カバレッジレポートがソースファイルよりも古い場合に、その旨をユーザーに通知する機能を追加するものです。これにより、ユーザーは表示されているカバレッジ情報が最新のものではないことを認識し、必要に応じてカバレッジレポートを再生成するなどの対応を取ることができます。
コミット
commit dccf651b24831a3f3f2657cf211129bb03c18ed4
Author: Aaron France <aaron.l.france@gmail.com>
Date: Mon Aug 19 16:32:00 2013 -0400
misc/emacs: Detect stale coverage reports
When the coverage report file is older than the file we're
showing the coverage report for, then we show a simple message
to state this fact.
R=adonovan, dominik.honnef, bradfitz
CC=golang-dev
https://golang.org/cl/12919044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/dccf651b24831a3f3f2657cf211129bb03c18ed4
元コミット内容
このコミットの目的は、EmacsのGoモードにおいて、表示されているカバレッジレポートが、そのレポートの対象となっているソースファイルよりも古い場合に、その状態を検出してユーザーに通知することです。具体的には、「カバレッジファイルがソースファイルよりも古い」というメッセージを表示します。
変更の背景
Go言語には、go test -cover
コマンドによってコードカバレッジを測定し、その結果をファイルに出力する機能があります。EmacsのGoモードは、このカバレッジレポートを読み込み、ソースコード上にカバレッジ情報をオーバーレイ表示する機能を提供しています。
しかし、ソースコードを編集した後、カバレッジレポートを再生成し忘れると、Emacsに表示されるカバレッジ情報は古いままになってしまいます。これにより、開発者は誤ったカバレッジ情報に基づいて判断を下してしまう可能性があります。
このコミットは、このような「古いカバレッジレポート」の問題を解決するために導入されました。カバレッジレポートファイルの最終更新時刻と、対象となるソースファイルの最終更新時刻を比較することで、レポートが古いかどうかを判断し、ユーザーに警告を発することで、常に最新のカバレッジ情報に基づいて作業を進められるように支援します。
前提知識の解説
Emacs Lisp (Elisp)
Emacs Lispは、Emacsエディタの拡張言語です。Emacsのほとんどの機能はEmacs Lispで書かれており、ユーザーはEmacs Lispを使ってEmacsをカスタマイズしたり、新しい機能を追加したりできます。このコミットで変更されているgo-mode.el
もEmacs Lispで書かれたファイルです。
Go言語のコードカバレッジ
Go言語では、go test -coverprofile=coverage.out
のようにコマンドを実行することで、テスト実行時のコードカバレッジ情報をcoverage.out
のようなファイルに出力できます。このファイルには、どのコード行がテストによって実行されたか(またはされなかったか)の情報が含まれています。
go-mode.el
go-mode.el
は、EmacsでGo言語のコードを編集するためのメジャーモードです。シンタックスハイライト、インデント、コード補完、そして本コミットに関連するコードカバレッジの表示など、Go言語開発を支援する様々な機能を提供します。
ファイルの属性とタイムスタンプ
ファイルシステム上の各ファイルには、最終更新時刻(modification time, mtime)などの属性が関連付けられています。これらのタイムスタンプは、ファイルが最後に変更された日時を示します。このコミットでは、カバレッジレポートファイルとソースファイルのmtimeを比較することで、どちらが新しいかを判断しています。
技術的詳細
このコミットの核心は、Emacs Lispの以下の関数を使用してファイルのタイムスタンプを取得し、比較することにあります。
file-attributes FILENAME
:FILENAME
で指定されたファイルの属性リストを返します。このリストの6番目の要素(インデックス5)は、ファイルの最終更新時刻(mtime)を表すタイムスタンプオブジェクトです。float-time TIME
: タイムスタンプオブジェクトTIME
を浮動小数点数に変換します。これにより、異なるファイルのタイムスタンプを数値として直接比較できるようになります。
変更箇所では、まずカバレッジレポートファイル(coverage-file
)と、カバレッジを表示している現在のソースファイル(origin-buffer
のファイル名)のfile-attributes
を取得します。
次に、それぞれのファイルのmtime(cov-mtime
とcur-mtime
)を抽出し、float-time
を使って浮動小数点数に変換します。
そして、(< (float-time cov-mtime) (float-time cur-mtime))
という条件式で、カバレッジファイルのmtimeがソースファイルのmtimeよりも古いかどうかをチェックします。
この条件が真(つまり、カバレッジファイルがソースファイルよりも古い)の場合、message
関数を使ってEmacsのミニバッファに「Coverage file is older than the source file.」という警告メッセージを表示します。
このシンプルな比較により、ユーザーはカバレッジ情報が最新ではない可能性を即座に知ることができます。
コアとなるコードの変更箇所
変更はmisc/emacs/go-mode.el
ファイル内のgo-coverage-mode
関数(またはそれに近いカバレッジ表示ロジックの一部)で行われています。
--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -1110,7 +1110,13 @@ for."
(coverage-file (or coverage-file (go--coverage-file)))\
(ranges-and-divisor (go--coverage-parse-file\
coverage-file\
- (file-name-nondirectory (buffer-file-name origin-buffer)))))\
+ (file-name-nondirectory (buffer-file-name origin-buffer))))\
+ (cov-mtime (nth 5 (file-attributes coverage-file)))\
+ (cur-mtime (nth 5 (file-attributes (buffer-file-name origin-buffer)))))\
+\
+ (if (< (float-time cov-mtime) (float-time cur-mtime))\
+ (message "Coverage file is older than the source file."))\
+\
(with-current-buffer (or (get-buffer gocov-buffer-name)\
(make-indirect-buffer origin-buffer gocov-buffer-name t))\
(set (make-local-variable 'go--coverage-origin-buffer) origin-buffer)\
コアとなるコードの解説
追加された行は以下の通りです。
(cov-mtime (nth 5 (file-attributes coverage-file)))
coverage-file
(カバレッジレポートファイルのパス)のファイル属性を取得し、そのリストの6番目の要素(インデックス5)である最終更新時刻(mtime)をcov-mtime
変数に格納します。
(cur-mtime (nth 5 (file-attributes (buffer-file-name origin-buffer))))
origin-buffer
(カバレッジを表示している現在のソースバッファ)のファイル名を取得し、そのファイルの属性からmtimeを抽出し、cur-mtime
変数に格納します。
(if (< (float-time cov-mtime) (float-time cur-mtime))
cov-mtime
とcur-mtime
をそれぞれfloat-time
で浮動小数点数に変換し、カバレッジファイルのmtimeがソースファイルのmtimeよりも古いかどうかを比較します。
(message "Coverage file is older than the source file."))
- 上記の
if
条件が真(カバレッジファイルが古い)の場合、Emacsのミニバッファに警告メッセージを表示します。
- 上記の
この変更により、カバレッジ表示のロジックに、ファイルのタイムスタンプ比較による「鮮度チェック」が組み込まれました。
関連リンク
- Go言語のテストとカバレッジ: https://go.dev/blog/cover
- Emacs Lispのドキュメント: https://www.gnu.org/software/emacs/manual/html_node/elisp/
- Go言語のEmacsモード(go-mode)のソースコード: https://github.com/golang/go/blob/master/misc/emacs/go-mode.el
参考にした情報源リンク
- Go言語の公式ドキュメント
- Emacs Lispの公式ドキュメント
- GitHubのgolang/goリポジトリのコミット履歴
- Go言語のコードカバレッジに関するブログ記事
- Emacs Lispの
file-attributes
およびfloat-time
関数のドキュメント - コミットメッセージ内のGo CLリンク:
https://golang.org/cl/12919044
(現在はhttps://go.dev/cl/12919044
にリダイレクトされる可能性があります)