[インデックス 17345] ファイルの概要
このコミットは、Go 1.2 リリースノートのドキュメントファイル doc/go1.2.txt
に対する変更です。具体的には、archive/tar
および archive/zip
パッケージにおける os.FileInfo
の実装に関する破壊的変更について追記しています。
コミット
commit 478c871f02f3b1b9b5c768a5d19fe7450b760dfd
Author: Rob Pike <r@golang.org>
Date: Wed Aug 21 08:37:32 2013 +1000
doc/go1.2.txt: archive/tar's fixed FileInfo
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/13140043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/478c871f02f3b1b9b5c768a5d19fe7450b760dfd
元コミット内容
doc/go1.2.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/go1.2.txt b/doc/go1.2.txt
index e23a579d5c..85dd2e2c56 100644
--- a/doc/go1.2.txt
+++ b/doc/go1.2.txt
@@ -14,6 +14,9 @@ crypto/des: 5x faster encoding/decoding (CL 11874043, 12072045).
encoding/json: faster encoding (CL 9129044).
net: improve windows performance by up to 30% (CL 8670044).
+Breaking change:
+archive/tar,archive/zip: fix os.FileInfo implementation to provide base name only (CL 13118043).
+\n cmd/5a: removed support for R9/R10 (use m/g instead) (CL 9840043).
cmd/5l: add MOVBS, MOVHS etc for sub-word moves (CL 12682043).
cmd/cgo, cmd/go: support including C++ code with cgo (CL 8248043).
変更の背景
このコミットは、Go 1.2 のリリースノートに、archive/tar
および archive/zip
パッケージにおける重要な破壊的変更を明記するために行われました。この変更は、os.FileInfo
インターフェースの実装が、ファイル名として完全なパスではなく、ベース名(ファイル名のみでディレクトリ情報は含まない)のみを返すように修正されたことによるものです。
Go の標準ライブラリでは、os.FileInfo
インターフェースはファイルに関するメタデータ(名前、サイズ、パーミッション、更新時刻など)を提供します。Name()
メソッドは、通常、ファイルまたはディレクトリのベース名を返すと期待されます。しかし、以前の archive/tar
および archive/zip
パッケージの実装では、os.FileInfo.Name()
がアーカイブ内のエントリの完全なパスを返してしまうという問題がありました。これは、os.FileInfo
の一般的なセマンティクスと矛盾し、このインターフェースを利用する他の Go コードとの互換性の問題を引き起こす可能性がありました。
この不整合を修正し、os.FileInfo
の期待される動作に合わせるために、archive/tar
および archive/zip
パッケージの os.FileInfo
実装が変更されました。この修正は、既存のコードが os.FileInfo.Name()
の戻り値に完全なパスを期待している場合に、予期せぬ動作やバグを引き起こす可能性があるため、「破壊的変更 (Breaking change)」としてリリースノートに記載する必要がありました。
前提知識の解説
Go 言語
Go(Golang)は、Googleによって開発されたオープンソースのプログラミング言語です。静的型付け、コンパイル型言語であり、並行処理、ガベージコレクション、メモリ安全性に重点を置いています。システムプログラミング、Webサービス、ネットワークプログラミングなどで広く利用されています。
os.FileInfo
インターフェース
Go の標準ライブラリ os
パッケージには、ファイルシステム上のファイルやディレクトリに関する情報を提供する FileInfo
インターフェースが定義されています。このインターフェースは以下のメソッドを持ちます。
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() interface{} // underlying data source (can return nil)
}
特に重要なのは Name()
メソッドで、これは「ファイルのベース名」を返すことが期待されています。ベース名とは、パスの最後の要素、つまりファイル名自体であり、ディレクトリパスは含まれません。例えば、/path/to/file.txt
のベース名は file.txt
です。
archive/tar
および archive/zip
パッケージ
archive/tar
: TARアーカイブ(テープアーカイブ)の読み書きを実装したパッケージです。TARファイルは、複数のファイルを一つのアーカイブにまとめるための一般的な形式です。archive/zip
: ZIPアーカイブの読み書きを実装したパッケージです。ZIPファイルもまた、ファイルを圧縮してアーカイブするための広く使われている形式です。
これらのパッケージは、アーカイブ内の各エントリ(ファイルやディレクトリ)を表現するために os.FileInfo
インターフェースを利用していました。
破壊的変更 (Breaking Change)
ソフトウェア開発において、破壊的変更とは、新しいバージョンのソフトウェアが古いバージョンと互換性がなく、古いバージョンで動作していたコードが新しいバージョンでは動作しなくなるような変更を指します。APIのシグネチャ変更、セマンティクスの変更、機能の削除などがこれに該当します。Go のような安定性を重視する言語では、破壊的変更は慎重に行われ、通常はリリースノートで明確に文書化されます。
技術的詳細
このコミットが参照している CL 13118043
は、archive/tar
および archive/zip
パッケージにおける os.FileInfo.Name()
メソッドの動作を修正するものです。
以前の実装では、archive/tar
の tar.Header
構造体や archive/zip
の zip.File
構造体が os.FileInfo
インターフェースを実装する際に、Name()
メソッドがアーカイブ内のエントリの完全なパス(例: dir/subdir/file.txt
)を返していました。これは、os.FileInfo
のドキュメントに記載されている「ベース名」を返すというセマンティクスに反していました。
この修正により、tar.Header
および zip.File
の Name()
メソッドは、filepath.Base()
関数を使用して、エントリのパスからベース名のみを抽出して返すようになりました。
例えば、アーカイブ内に foo/bar/baz.txt
というエントリがあった場合:
- 修正前:
os.FileInfo.Name()
はfoo/bar/baz.txt
を返していた。 - 修正後:
os.FileInfo.Name()
はbaz.txt
を返すようになった。
この変更は、os.FileInfo
インターフェースの契約を遵守し、Go エコシステム全体での一貫性を保つために不可欠でした。しかし、もし開発者が archive/tar
や archive/zip
から取得した os.FileInfo
の Name()
メソッドが完全なパスを返すことに依存していた場合、この変更によってそのコードは正しく動作しなくなります。そのため、Go 1.2 のリリースノートに「Breaking change」として明記する必要がありました。
コアとなるコードの変更箇所
このコミット自体は、doc/go1.2.txt
というドキュメントファイルに3行を追加するものです。
--- a/doc/go1.2.txt
+++ b/doc/go1.2.txt
@@ -14,6 +14,9 @@ crypto/des: 5x faster encoding/decoding (CL 11874043, 12072045).
encoding/json: faster encoding (CL 9129044).
net: improve windows performance by up to 30% (CL 8670044).
+Breaking change:
+archive/tar,archive/zip: fix os.FileInfo implementation to provide base name only (CL 13118043).
+\n cmd/5a: removed support for R9/R10 (use m/g instead) (CL 9840043).
cmd/5l: add MOVBS, MOVHS etc for sub-word moves (CL 12682043).
cmd/cgo, cmd/go: support including C++ code with cgo (CL 8248043).
追加された行は以下の通りです。
Breaking change:
archive/tar,archive/zip: fix os.FileInfo implementation to provide base name only (CL 13118043).
この変更は、Go 1.2 のリリースノートに、archive/tar
と archive/zip
パッケージの os.FileInfo
実装に関する破壊的変更を明確に記載するためのものです。
コアとなるコードの解説
このコミット自体は Go のソースコードの動作を変更するものではなく、Go 1.2 のリリースノート (doc/go1.2.txt
) に情報を追加するものです。したがって、直接的な「コアとなるコードの解説」は、このコミットの範囲内にはありません。
しかし、このコミットが言及している CL 13118043
で行われた実際のコード変更は、archive/tar
と archive/zip
パッケージの内部実装にあります。具体的には、tar.Header
と zip.File
が os.FileInfo
インターフェースを実装する際の Name()
メソッドのロジックが変更されました。
例えば、archive/tar
パッケージでは、Header
構造体が os.FileInfo
を実装しており、その Name()
メソッドは以下のように変更されました(概念的な説明であり、実際のコードはより複雑な場合があります):
変更前 (概念):
func (h *Header) Name() string {
return h.Name // h.Name が完全なパスを保持していた
}
変更後 (概念):
import "path/filepath"
func (h *Header) Name() string {
return filepath.Base(h.Name) // h.Name からベース名のみを抽出
}
同様の変更が archive/zip
パッケージの zip.File
構造体にも適用されました。この修正により、os.FileInfo
の Name()
メソッドが常にベース名を返すという Go の慣習と期待に沿うようになりました。
関連リンク
- Go 1.2 Release Notes (最終版): https://go.dev/doc/go1.2
- Go issue 5906: archive/tar: FileInfo.Name should be base name: https://github.com/golang/go/issues/5906
- Go issue 5907: archive/zip: FileInfo.Name should be base name: https://github.com/golang/go/issues/5907
- CL 13118043 (実際の修正コミット): https://go.dev/cl/13118043
参考にした情報源リンク
- Go 言語公式ドキュメント: https://go.dev/doc/
os
パッケージドキュメント: https://pkg.go.dev/osarchive/tar
パッケージドキュメント: https://pkg.go.dev/archive/tararchive/zip
パッケージドキュメント: https://pkg.go.dev/archive/zippath/filepath
パッケージドキュメント: https://pkg.go.dev/path/filepath- GitHub Go リポジトリ: https://github.com/golang/go
- Go Code Review Comments (CL): https://go.dev/doc/contribute#code_reviews
- Go 1.2 Release Notes (draft/development version, as seen in the commit): https://go.googlesource.com/go/+/refs/heads/master/doc/go1.2.txt (これはコミット時点のドラフト版であり、最終版は go.dev にあります)