[インデックス 10855] ファイルの概要
このコミットは、Go言語のビルドシステム (go/build
パッケージ) におけるエラーメッセージから、冗長なプレフィックス "go/build:"
を削除する変更です。これにより、特に goinstall
コマンドを使用する際に表示されるエラーメッセージがより分かりやすくなり、ユーザーの混乱を避けることを目的としています。
コミット
- コミットハッシュ:
96a5780db882b4bd4a1f4b69e185833e5bedffcb
- Author: Andrew Gerrand adg@golang.org
- Date: Sat Dec 17 13:14:18 2011 +1100
- コミットメッセージ:
go/build: remove 'go/build' from error messages This leads to really confusing messages in goinstall. R=golang-dev, r CC=golang-dev https://golang.org/cl/5495074
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/96a5780db882b4bd4a1f4b69e185833e5bedffcb
元コミット内容
commit 96a5780db882b4bd4a1f4b69e185833e5bedffcb
Author: Andrew Gerrand <adg@golang.org>
Date: Sat Dec 17 13:14:18 2011 +1100
go/build: remove 'go/build' from error messages
This leads to really confusing messages in goinstall.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5495074
---\n src/pkg/go/build/path.go | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/src/pkg/go/build/path.go b/src/pkg/go/build/path.go
index 91d6c430a9..5b4d9243e6 100644
--- a/src/pkg/go/build/path.go
+++ b/src/pkg/go/build/path.go
@@ -85,8 +85,8 @@ func (t *Tree) HasPkg(pkg string) bool {
}\n \n var (\n-\tErrNotFound = errors.New(\"go/build: package could not be found locally\")\n-\tErrTreeNotFound = errors.New(\"go/build: no valid GOROOT or GOPATH could be found\")\n+\tErrNotFound = errors.New(\"package could not be found locally\")\n+\tErrTreeNotFound = errors.New(\"no valid GOROOT or GOPATH could be found\")\n )\n \n // FindTree takes an import or filesystem path and returns the\n@@ -151,7 +151,7 @@ func init() {\n \troot := runtime.GOROOT()\n \tt, err := newTree(root)\n \tif err != nil {\n-\t\tlog.Printf(\"go/build: invalid GOROOT %q: %v\", root, err)\n+\t\tlog.Printf(\"invalid GOROOT %q: %v\", root, err)\n \t} else {\n \t\tt.Goroot = true\n \t\tPath = []*Tree{t}\n@@ -163,7 +163,7 @@ func init() {\n \t\t}\n \t\tt, err := newTree(p)\n \t\tif err != nil {\n-\t\t\tlog.Printf(\"go/build: invalid GOPATH %q: %v\", p, err)\n+\t\t\tlog.Printf(\"invalid GOPATH %q: %v\", p, err)\n \t\t\tcontinue\n \t\t}\n \t\tPath = append(Path, t)\n```
## 変更の背景
この変更の背景には、Go言語の初期のツールチェインにおけるユーザーエクスペリエンスの改善があります。コミットメッセージに「This leads to really confusing messages in goinstall.」とあるように、`goinstall` コマンドが `go/build` パッケージから返されるエラーメッセージをそのまま表示すると、ユーザーにとって非常に分かりにくいメッセージになっていました。
具体的には、エラーメッセージの冒頭に常に `"go/build:"` というプレフィックスが付与されていたため、例えば「`go/build: package could not be found locally`」のようなメッセージが表示されていました。これは、エラーが `go/build` パッケージ内で発生したことを示していますが、エンドユーザーにとっては、どのツールがエラーを出しているのか、あるいはエラーの根本原因が何なのかを理解する上で、このプレフィックスはむしろノイズとなっていました。
`goinstall` は、Goのパッケージをダウンロード、ビルド、インストールするための初期のツールであり、ユーザーがGoのコードを扱う上で頻繁に利用するものでした。そのため、このツールが出力するエラーメッセージの明確さは非常に重要でした。開発者は、エラーメッセージが冗長であることによって、ユーザーが問題解決に余計な時間を費やしたり、誤解したりする可能性を懸念し、この改善を決定しました。
この変更は、Go言語の設計哲学の一つである「シンプルさ」と「実用性」にも合致しています。ユーザーが直面する問題を最小限に抑え、より直感的な開発体験を提供するための、細かながらも重要な改善と言えます。
## 前提知識の解説
このコミットを理解するためには、以下のGo言語の基本的な概念とツールに関する知識が必要です。
### Go言語のパッケージとビルドシステム
Go言語のコードは「パッケージ」という単位で管理されます。パッケージは関連するGoのソースファイル (`.go` ファイル) の集まりであり、他のパッケージからインポートして利用することができます。
Goのビルドシステムは、これらのパッケージをコンパイルし、実行可能なバイナリやライブラリを生成する役割を担っています。
### `go/build` パッケージ
`go/build` パッケージは、Goのソースコードを解析し、パッケージの依存関係を解決し、ビルドに必要な情報を収集するための低レベルなAPIを提供します。このパッケージは、Goの標準ツールチェイン(`go build`, `go install`, `go get` など)の基盤として機能します。
このコミットで変更されている `path.go` ファイルは、`go/build` パッケージの一部であり、Goのソースコードやパッケージがファイルシステム上のどこに存在するかを特定するためのロジックを含んでいます。
### `GOROOT` と `GOPATH`
Goの環境変数である `GOROOT` と `GOPATH` は、Goのビルドシステムがパッケージを見つけるために非常に重要です。
* **`GOROOT`**: GoのSDK(標準ライブラリ、ツールなど)がインストールされているディレクトリを指します。Goの標準パッケージは `GOROOT` 内に存在します。
* **`GOPATH`**: ユーザーが開発するGoのプロジェクトや、`go get` コマンドでダウンロードされたサードパーティのパッケージが配置されるワークスペースのルートディレクトリを指します。Go 1.11以降のGo Modulesの導入により、`GOPATH` の役割は変化しましたが、このコミットが作成された2011年当時は、`GOPATH` がGo開発における主要なワークスペースでした。
`go/build` パッケージは、これらの環境変数を参照して、指定されたパッケージのソースコードを検索します。
### `goinstall` コマンド
`goinstall` は、Go言語の初期のバージョンで提供されていたコマンドラインツールです。これは、指定されたGoパッケージをインターネットからダウンロードし、コンパイルし、インストールする機能を持っていました。現在の `go get` コマンドの前身にあたります。
このツールは、Goのパッケージ管理と依存関係解決の初期段階を担っており、ユーザーが新しいライブラリやアプリケーションを簡単に導入できるように設計されていました。
### Goのエラーハンドリング
Go言語では、エラーは戻り値として明示的に扱われます。関数は通常、最後の戻り値として `error` 型の値を返します。エラーが発生しなかった場合は `nil` を返します。
`errors.New()` 関数は、新しいエラー値を生成するために使用されます。このコミットでは、`ErrNotFound` と `ErrTreeNotFound` という2つのエラー変数が `errors.New()` を使って定義されています。
### `log.Printf`
`log` パッケージは、Goの標準ライブラリの一部であり、ログメッセージを出力するための機能を提供します。`log.Printf` は、フォーマット文字列と引数を受け取り、標準エラー出力(または設定された出力先)にログメッセージを出力します。
このコミットでは、`GOROOT` や `GOPATH` が無効な場合にログメッセージを出力するために `log.Printf` が使用されています。
## 技術的詳細
このコミットの技術的な詳細は、Go言語のエラーメッセージの設計と、ユーザーへの情報提供のバランスに関するものです。
### エラーメッセージの冗長性の排除
Go言語のエラーメッセージは、通常、問題の内容を簡潔かつ明確に伝えるべきであるという原則があります。このコミット以前は、`go/build` パッケージが生成するエラーメッセージには、常にそのパッケージ名である `"go/build:"` というプレフィックスが付加されていました。
例えば、パッケージが見つからない場合のエラーは `errors.New("go/build: package could not be found locally")` と定義されていました。これは、エラーが `go/build` パッケージの内部で発生したことを示していますが、この情報がエンドユーザーにとって常に有用であるとは限りません。特に、`goinstall` のような上位レベルのツールがこれらのエラーをそのまま表示する場合、ユーザーは「`goinstall` が `go/build` パッケージを使って何かをしようとしたが、それが失敗した」という間接的な情報を得るだけで、直接的な問題解決には繋がりにくいと感じる可能性がありました。
この変更は、この冗長なプレフィックスを削除することで、エラーメッセージをより直接的で分かりやすいものにすることを目的としています。例えば、「`package could not be found locally`」というメッセージは、ユーザーが探しているパッケージが見つからなかったという事実を直接的に伝えます。これにより、ユーザーはエラーメッセージを解釈する手間が省け、問題の特定と解決に集中できるようになります。
### `errors.New` とログメッセージの変更
コミットの差分を見ると、以下の2種類のエラーメッセージと2種類のログメッセージが変更されています。
1. **`ErrNotFound` と `ErrTreeNotFound` の定義**:
これらのエラー変数は、`go/build` パッケージ内で定義されている公開エラーです。以前は `errors.New("go/build: ...")` の形式で定義されていましたが、変更後は `"go/build:"` プレフィックスが削除され、`errors.New("...")` の形式になりました。
これは、これらのエラーが `go/build` パッケージの外部に公開され、他のパッケージやツールによって捕捉・表示される可能性があるため、その際に冗長なプレフィックスが表示されないようにするためです。
2. **`log.Printf` で出力されるメッセージ**:
`init()` 関数内で `GOROOT` や `GOPATH` の設定が不正な場合に `log.Printf` を使ってログメッセージが出力されていました。以前は `log.Printf("go/build: invalid GOROOT %q: %v", ...)` の形式でしたが、これも `"go/build:"` プレフィックスが削除されました。
ログメッセージの場合も、同様に冗長な情報を排除し、より簡潔に問題の内容を伝えることを目的としています。ログは開発者やシステム管理者が見るものですが、それでもメッセージは明確であるべきです。
### 影響とメリット
この変更による主なメリットは以下の通りです。
* **ユーザーエクスペリエンスの向上**: `goinstall` などのツールが出力するエラーメッセージがより簡潔になり、ユーザーがエラーの原因を迅速に理解できるようになります。
* **メッセージの一貫性**: Goのエラーメッセージの一般的な慣習に沿う形となり、他のGoツールやライブラリのエラーメッセージとの一貫性が向上します。
* **コードの簡潔化**: エラーメッセージの定義がわずかに短くなり、コードの可読性も向上します。
この変更は、Go言語のツールチェインが成熟していく過程で、ユーザーからのフィードバックや開発者の経験に基づいて行われた、細かながらも重要な改善の一例と言えます。
## コアとなるコードの変更箇所
変更は `src/pkg/go/build/path.go` ファイルに集中しています。
```diff
--- a/src/pkg/go/build/path.go
+++ b/src/pkg/go/build/path.go
@@ -85,8 +85,8 @@ func (t *Tree) HasPkg(pkg string) bool {
}
var (
- ErrNotFound = errors.New("go/build: package could not be found locally")
- ErrTreeNotFound = errors.New("go/build: no valid GOROOT or GOPATH could be found")
+ ErrNotFound = errors.New("package could not be found locally")
+ ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)
// FindTree takes an import or filesystem path and returns the
@@ -151,7 +151,7 @@ func init() {
root := runtime.GOROOT()
t, err := newTree(root)
if err != nil {
- log.Printf("go/build: invalid GOROOT %q: %v", root, err)
+ log.Printf("invalid GOROOT %q: %v", root, err)
} else {
t.Goroot = true
Path = []*Tree{t}
@@ -163,7 +163,7 @@ func init() {
}
t, err := newTree(p)
if err != nil {
- log.Printf("go/build: invalid GOPATH %q: %v", p, err)
+ log.Printf("invalid GOPATH %q: %v", p, err)
}
Path = append(Path, t)
}
具体的には、以下の4箇所が変更されています。
ErrNotFound
エラー変数の定義ErrTreeNotFound
エラー変数の定義init()
関数内のGOROOT
関連のlog.Printf
呼び出しinit()
関数内のGOPATH
関連のlog.Printf
呼び出し
コアとなるコードの解説
このコミットのコアとなる変更は、エラーメッセージとログメッセージから "go/build:"
という文字列プレフィックスを削除することです。
エラー変数の定義変更
// 変更前
var (
ErrNotFound = errors.New("go/build: package could not be found locally")
ErrTreeNotFound = errors.New("go/build: no valid GOROOT or GOPATH could be found")
)
// 変更後
var (
ErrNotFound = errors.New("package could not be found locally")
ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)
ErrNotFound
は、指定されたパッケージがローカルのファイルシステム上で見つからなかった場合に返されるエラーです。
ErrTreeNotFound
は、有効な GOROOT
または GOPATH
が見つからなかった場合に返されるエラーです。
これらのエラーは go/build
パッケージの外部に公開される可能性があるため、このプレフィックスを削除することで、エラーを受け取った側(例えば goinstall
)がそのままメッセージを表示しても、冗長な情報が含まれないようになります。これにより、ユーザーは「パッケージが見つかりません」や「GOROOT
/GOPATH
が無効です」といった、より直接的なメッセージを受け取ることができます。
log.Printf
呼び出しの変更
// 変更前 (GOROOT関連)
if err != nil {
log.Printf("go/build: invalid GOROOT %q: %v", root, err)
}
// 変更後 (GOROOT関連)
if err != nil {
log.Printf("invalid GOROOT %q: %v", root, err)
}
// 変更前 (GOPATH関連)
if err != nil {
log.Printf("go/build: invalid GOPATH %q: %v", p, err)
continue
}
// 変更後 (GOPATH関連)
if err != nil {
log.Printf("invalid GOPATH %q: %v", p, err)
continue
}
init()
関数は、パッケージが初期化される際に自動的に実行される特別な関数です。この関数内で、GOROOT
と GOPATH
の設定を検証し、もし無効なパスが指定されていれば、log.Printf
を使って警告メッセージを出力しています。
ここでも同様に、ログメッセージから "go/build:"
プレフィックスが削除されています。ログは通常、開発者やシステム管理者がデバッグや問題診断のために参照するものですが、それでもメッセージは簡潔で分かりやすい方が好ましいです。この変更により、「invalid GOROOT
」や「invalid GOPATH
」といった、より直接的な警告がログに出力されるようになります。
これらの変更は、Go言語のエラーメッセージとログ出力の品質を向上させ、ユーザーと開発者の双方にとってより良い体験を提供するための、細部にわたる配慮を示しています。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
go/build
パッケージのドキュメント: https://pkg.go.dev/go/build (現在のバージョン)- Go Modules (Go 1.11以降のパッケージ管理): https://go.dev/blog/go-modules
参考にした情報源リンク
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go Code Review Comments (Effective Go): https://go.dev/doc/effective_go#errors (エラーメッセージに関する一般的なGoの慣習)
goinstall
の歴史に関する情報 (Goの初期のツールチェインに関するブログ記事やディスカッション):- Go 1 Release Notes (goinstallからgo getへの移行に関する言及がある可能性): https://go.dev/doc/go1
- Goの初期のメーリングリストアーカイブ (golang-nuts, golang-dev): https://groups.google.com/g/golang-nuts (当時の議論を検索することで、
goinstall
の問題点やエラーメッセージに関する議論が見つかる可能性があります。)
- Goのソースコード (特に
src/cmd/go/
ディレクトリ内のgoinstall
に関連するコードや、src/pkg/go/build/
ディレクトリ内の他のファイル): https://github.com/golang/go - GoのIssue Tracker (当時の関連するIssueや提案): https://github.com/golang/go/issues
- GoのChange List (CL) 5495074: https://golang.org/cl/5495074 (このコミットの元となったコードレビューのページ。詳細な議論や背景情報が含まれている可能性があります。)
[インデックス 10855] ファイルの概要
このコミットは、Go言語のビルドシステム (go/build
パッケージ) におけるエラーメッセージから、冗長なプレフィックス "go/build:"
を削除する変更です。これにより、特に goinstall
コマンドを使用する際に表示されるエラーメッセージがより分かりやすくなり、ユーザーの混乱を避けることを目的としています。
コミット
- コミットハッシュ:
96a5780db882b4bd4a1f4b69e185833e5bedffcb
- Author: Andrew Gerrand adg@golang.org
- Date: Sat Dec 17 13:14:18 2011 +1100
- コミットメッセージ:
go/build: remove 'go/build' from error messages This leads to really confusing messages in goinstall. R=golang-dev, r CC=golang-dev https://golang.org/cl/5495074
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/96a5780db882b4bd4a1f4b69e185833e5bedffcb
元コミット内容
commit 96a5780db882b4bd4a1f4b69e185833e5bedffcb
Author: Andrew Gerrand <adg@golang.org>
Date: Sat Dec 17 13:14:18 2011 +1100
go/build: remove 'go/build' from error messages
This leads to really confusing messages in goinstall.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5495074
---
src/pkg/go/build/path.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/pkg/go/build/path.go b/src/pkg/go/build/path.go
index 91d6c430a9..5b4d9243e6 100644
--- a/src/pkg/go/build/path.go
+++ b/src/pkg/go/build/path.go
@@ -85,8 +85,8 @@ func (t *Tree) HasPkg(pkg string) bool {
}
var (
- ErrNotFound = errors.New("go/build: package could not be found locally")
- ErrTreeNotFound = errors.New("go/build: no valid GOROOT or GOPATH could be found")
+ ErrNotFound = errors.New("package could not be found locally")
+ ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)
// FindTree takes an import or filesystem path and returns the
@@ -151,7 +151,7 @@ func init() {
root := runtime.GOROOT()
t, err := newTree(root)
if err != nil {
- log.Printf("go/build: invalid GOROOT %q: %v", root, err)
+ log.Printf("invalid GOROOT %q: %v", root, err)
} else {
t.Goroot = true
Path = []*Tree{t}
@@ -163,7 +163,7 @@ func init() {
}
t, err := newTree(p)
if err != nil {
- log.Printf("go/build: invalid GOPATH %q: %v", p, err)
+ log.Printf("invalid GOPATH %q: %v", p, err)
}
Path = append(Path, t)
}
変更の背景
この変更の背景には、Go言語の初期のツールチェインにおけるユーザーエクスペリエンスの改善があります。コミットメッセージに「This leads to really confusing messages in goinstall.」とあるように、goinstall
コマンドが go/build
パッケージから返されるエラーメッセージをそのまま表示すると、ユーザーにとって非常に分かりにくいメッセージになっていました。
具体的には、エラーメッセージの冒頭に常に "go/build:"
というプレフィックスが付与されていたため、例えば「go/build: package could not be found locally
」のようなメッセージが表示されていました。これは、エラーが go/build
パッケージ内で発生したことを示していますが、エンドユーザーにとっては、どのツールがエラーを出しているのか、あるいはエラーの根本原因が何なのかを理解する上で、このプレフィックスはむしろノイズとなっていました。
goinstall
は、Goのパッケージをダウンロード、ビルド、インストールするための初期のツールであり、ユーザーがGoのコードを扱う上で頻繁に利用するものでした。そのため、このツールが出力するエラーメッセージの明確さは非常に重要でした。開発者は、エラーメッセージが冗長であることによって、ユーザーが問題解決に余計な時間を費やしたり、誤解したりする可能性を懸念し、この改善を決定しました。
この変更は、Go言語の設計哲学の一つである「シンプルさ」と「実用性」にも合致しています。ユーザーが直面する問題を最小限に抑え、より直感的な開発体験を提供するための、細かながらも重要な改善と言えます。
前提知識の解説
このコミットを理解するためには、以下のGo言語の基本的な概念とツールに関する知識が必要です。
Go言語のパッケージとビルドシステム
Go言語のコードは「パッケージ」という単位で管理されます。パッケージは関連するGoのソースファイル (.go
ファイル) の集まりであり、他のパッケージからインポートして利用することができます。
Goのビルドシステムは、これらのパッケージをコンパイルし、実行可能なバイナリやライブラリを生成する役割を担っています。
go/build
パッケージ
go/build
パッケージは、Goのソースコードを解析し、パッケージの依存関係を解決し、ビルドに必要な情報を収集するための低レベルなAPIを提供します。このパッケージは、Goの標準ツールチェイン(go build
, go install
, go get
など)の基盤として機能します。
このコミットで変更されている path.go
ファイルは、go/build
パッケージの一部であり、Goのソースコードやパッケージがファイルシステム上のどこに存在するかを特定するためのロジックを含んでいます。
GOROOT
と GOPATH
Goの環境変数である GOROOT
と GOPATH
は、Goのビルドシステムがパッケージを見つけるために非常に重要です。
GOROOT
: GoのSDK(標準ライブラリ、ツールなど)がインストールされているディレクトリを指します。Goの標準パッケージはGOROOT
内に存在します。GOPATH
: ユーザーが開発するGoのプロジェクトや、go get
コマンドでダウンロードされたサードパーティのパッケージが配置されるワークスペースのルートディレクトリを指します。Go 1.11以降のGo Modulesの導入により、GOPATH
の役割は変化しましたが、このコミットが作成された2011年当時は、GOPATH
がGo開発における主要なワークスペースでした。
go/build
パッケージは、これらの環境変数を参照して、指定されたパッケージのソースコードを検索します。
goinstall
コマンド
goinstall
は、Go言語の初期のバージョンで提供されていたコマンドラインツールです。これは、指定されたGoパッケージをインターネットからダウンロードし、コンパイルし、インストールする機能を持っていました。現在の go get
コマンドの前身にあたります。
このツールは、Goのパッケージ管理と依存関係解決の初期段階を担っており、ユーザーが新しいライブラリやアプリケーションを簡単に導入できるように設計されていました。
Goのエラーハンドリング
Go言語では、エラーは戻り値として明示的に扱われます。関数は通常、最後の戻り値として error
型の値を返します。エラーが発生しなかった場合は nil
を返します。
errors.New()
関数は、新しいエラー値を生成するために使用されます。このコミットでは、ErrNotFound
と ErrTreeNotFound
という2つのエラー変数が errors.New()
を使って定義されています。
log.Printf
log
パッケージは、Goの標準ライブラリの一部であり、ログメッセージを出力するための機能を提供します。log.Printf
は、フォーマット文字列と引数を受け取り、標準エラー出力(または設定された出力先)にログメッセージを出力します。
このコミットでは、GOROOT
や GOPATH
が無効な場合にログメッセージを出力するために log.Printf
が使用されています。
技術的詳細
このコミットの技術的な詳細は、Go言語のエラーメッセージの設計と、ユーザーへの情報提供のバランスに関するものです。
エラーメッセージの冗長性の排除
Go言語のエラーメッセージは、通常、問題の内容を簡潔かつ明確に伝えるべきであるという原則があります。このコミット以前は、go/build
パッケージが生成するエラーメッセージには、常にそのパッケージ名である "go/build:"
というプレフィックスが付加されていました。
例えば、パッケージが見つからない場合のエラーは errors.New("go/build: package could not be found locally")
と定義されていました。これは、エラーが go/build
パッケージの内部で発生したことを示していますが、この情報がエンドユーザーにとって常に有用であるとは限りません。特に、goinstall
のような上位レベルのツールがこれらのエラーをそのまま表示する場合、ユーザーは「goinstall
が go/build
パッケージを使って何かをしようとしたが、それが失敗した」という間接的な情報を得るだけで、直接的な問題解決には繋がりにくいと感じる可能性がありました。
この変更は、この冗長なプレフィックスを削除することで、エラーメッセージをより直接的で分かりやすいものにすることを目的としています。例えば、「package could not be found locally
」というメッセージは、ユーザーが探しているパッケージが見つからなかったという事実を直接的に伝えます。これにより、ユーザーはエラーメッセージを解釈する手間が省け、問題の特定と解決に集中できるようになります。
errors.New
とログメッセージの変更
コミットの差分を見ると、以下の2種類のエラーメッセージと2種類のログメッセージが変更されています。
-
ErrNotFound
とErrTreeNotFound
の定義: これらのエラー変数は、go/build
パッケージ内で定義されている公開エラーです。以前はerrors.New("go/build: ...")
の形式で定義されていましたが、変更後は"go/build:"
プレフィックスが削除され、errors.New("...")
の形式になりました。 これは、これらのエラーがgo/build
パッケージの外部に公開され、他のパッケージやツールによって捕捉・表示される可能性があるため、その際に冗長なプレフィックスが表示されないようにするためです。 -
log.Printf
で出力されるメッセージ:init()
関数内でGOROOT
やGOPATH
の設定が不正な場合にlog.Printf
を使ってログメッセージが出力されていました。以前はlog.Printf("go/build: invalid GOROOT %q: %v", ...)
の形式でしたが、これも"go/build:"
プレフィックスが削除されました。 ログメッセージの場合も、同様に冗長な情報を排除し、より簡潔に問題の内容を伝えることを目的としています。ログは開発者やシステム管理者が見るものですが、それでもメッセージは明確であるべきです。
影響とメリット
この変更による主なメリットは以下の通りです。
- ユーザーエクスペリエンスの向上:
goinstall
などのツールが出力するエラーメッセージがより簡潔になり、ユーザーがエラーの原因を迅速に理解できるようになります。 - メッセージの一貫性: Goのエラーメッセージの一般的な慣習に沿う形となり、他のGoツールやライブラリのエラーメッセージとの一貫性が向上します。
- コードの簡潔化: エラーメッセージの定義がわずかに短くなり、コードの可読性も向上します。
この変更は、Go言語のツールチェインが成熟していく過程で、ユーザーからのフィードバックや開発者の経験に基づいて行われた、細かながらも重要な改善の一例と言えます。
コアとなるコードの変更箇所
変更は src/pkg/go/build/path.go
ファイルに集中しています。
--- a/src/pkg/go/build/path.go
+++ b/src/pkg/go/build/path.go
@@ -85,8 +85,8 @@ func (t *Tree) HasPkg(pkg string) bool {
}
var (
- ErrNotFound = errors.New("go/build: package could not be found locally")
- ErrTreeNotFound = errors.New("go/build: no valid GOROOT or GOPATH could be found")
+ ErrNotFound = errors.New("package could not be found locally")
+ ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)
// FindTree takes an import or filesystem path and returns the
@@ -151,7 +151,7 @@ func init() {
root := runtime.GOROOT()
t, err := newTree(root)
if err != nil {
- log.Printf("go/build: invalid GOROOT %q: %v", root, err)
+ log.Printf("invalid GOROOT %q: %v", root, err)
} else {
t.Goroot = true
Path = []*Tree{t}
@@ -163,7 +163,7 @@ func init() {
}
t, err := newTree(p)
if err != nil {
- log.Printf("go/build: invalid GOPATH %q: %v", p, err)
+ log.Printf("invalid GOPATH %q: %v", p, err)
}
Path = append(Path, t)
}
具体的には、以下の4箇所が変更されています。
ErrNotFound
エラー変数の定義ErrTreeNotFound
エラー変数の定義init()
関数内のGOROOT
関連のlog.Printf
呼び出しinit()
関数内のGOPATH
関連のlog.Printf
呼び出し
コアとなるコードの解説
このコミットのコアとなる変更は、エラーメッセージとログメッセージから "go/build:"
という文字列プレフィックスを削除することです。
エラー変数の定義変更
// 変更前
var (
ErrNotFound = errors.New("go/build: package could not be found locally")
ErrTreeNotFound = errors.New("go/build: no valid GOROOT or GOPATH could be found")
)
// 変更後
var (
ErrNotFound = errors.New("package could not be found locally")
ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)
ErrNotFound
は、指定されたパッケージがローカルのファイルシステム上で見つからなかった場合に返されるエラーです。
ErrTreeNotFound
は、有効な GOROOT
または GOPATH
が見つからなかった場合に返されるエラーです。
これらのエラーは go/build
パッケージの外部に公開される可能性があるため、このプレフィックスを削除することで、エラーを受け取った側(例えば goinstall
)がそのままメッセージを表示しても、冗長な情報が含まれないようになります。これにより、ユーザーは「パッケージが見つかりません」や「GOROOT
/GOPATH
が無効です」といった、より直接的なメッセージを受け取ることができます。
log.Printf
呼び出しの変更
// 変更前 (GOROOT関連)
if err != nil {
log.Printf("go/build: invalid GOROOT %q: %v", root, err)
}
// 変更後 (GOROOT関連)
if err != nil {
log.Printf("invalid GOROOT %q: %v", root, err)
}
// 変更前 (GOPATH関連)
if err != nil {
log.Printf("go/build: invalid GOPATH %q: %v", p, err)
continue
}
// 変更後 (GOPATH関連)
if err != nil {
log.Printf("invalid GOPATH %q: %v", p, err)
continue
}
init()
関数は、パッケージが初期化される際に自動的に実行される特別な関数です。この関数内で、GOROOT
と GOPATH
の設定を検証し、もし無効なパスが指定されていれば、log.Printf
を使って警告メッセージを出力しています。
ここでも同様に、ログメッセージから "go/build:"
プレフィックスが削除されています。ログは通常、開発者やシステム管理者がデバッグや問題診断のために参照するものですが、それでもメッセージは簡潔で分かりやすい方が好ましいです。この変更により、「invalid GOROOT
」や「invalid GOPATH
」といった、より直接的な警告がログに出力されるようになります。
これらの変更は、Go言語のエラーメッセージとログ出力の品質を向上させ、ユーザーと開発者の双方にとってより良い体験を提供するための、細部にわたる配慮を示しています。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
go/build
パッケージのドキュメント: https://pkg.go.dev/go/build (現在のバージョン)- Go Modules (Go 1.11以降のパッケージ管理): https://go.dev/blog/go-modules
参考にした情報源リンク
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go Code Review Comments (Effective Go): https://go.dev/doc/effective_go#errors (エラーメッセージに関する一般的なGoの慣習)
goinstall
の歴史に関する情報 (Goの初期のツールチェインに関するブログ記事やディスカッション):- Go 1 Release Notes (goinstallからgo getへの移行に関する言及がある可能性): https://go.dev/doc/go1
- Goの初期のメーリングリストアーカイブ (golang-nuts, golang-dev): https://groups.google.com/g/golang-nuts (当時の議論を検索することで、
goinstall
の問題点やエラーメッセージに関する議論が見つかる可能性があります。)
- Goのソースコード (特に
src/cmd/go/
ディレクトリ内のgoinstall
に関連するコードや、src/pkg/go/build/
ディレクトリ内の他のファイル): https://github.com/golang/go - GoのIssue Tracker (当時の関連するIssueや提案): https://github.com/golang/go/issues
- GoのChange List (CL) 5495074: https://golang.org/cl/5495074 (このコミットの元となったコードレビューのページ。詳細な議論や背景情報が含まれている可能性があります。)
- Web検索結果: "goinstall confusing error messages go/build" (Goのエラーメッセージが混乱を招く原因と、
goinstall
やGOPATH
との関連性に関する一般的な情報)