[インデックス 11454] ファイルの概要
このコミットは、Go言語のツール群である gofix
と govet
を、より簡潔な fix
と vet
へと名称変更し、go tool
コマンド体系の下に再配置する大規模な変更を伴います。これにより、Goのビルドシステムとツール管理がより整理され、ユーザーエクスペリエンスが向上します。
コミット
commit 71d83b72efe3e20ce6b0ab96226873074afe24be
Author: Rob Pike <r@golang.org>
Date: Sun Jan 29 11:07:25 2012 -0800
cmd/go: add go tools to rearrangement
fix, vet
yacc is also fixed (it was wrong before)
All that's left is the commands used during compilation
This looks like a huge CL, but it's almost all file renames.
The action is in cmd/go/pkg.go, the Makefiles, and .../doc.go.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5595044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/71d83b72efe3e20ce6b0ab96226873074afe24be
元コミット内容
このコミットの主な目的は、Go言語の標準ツールである gofix
と govet
を、それぞれ fix
と vet
という短い名前に変更し、go tool
コマンドのサブコマンドとして統合することです。これにより、Goのツールエコシステムがより一貫性のあるものになります。コミットメッセージにもあるように、変更の大部分はファイルのリネームであり、実質的なコードロジックの変更は限定的です。yacc
ツールもこの再編に含まれています。
変更の背景
Go言語の開発初期段階では、様々な補助ツールが個別に提供されていました。gofix
はGoのAPI変更に対応して古いコードを自動的に修正するツールとして、govet
はGoコードの静的解析を行い潜在的なバグを検出するツールとして、それぞれ独立したコマンドとして存在していました。
しかし、Goエコシステムの成長に伴い、これらのツールを go
コマンドの統一されたインターフェースの下に置くことが望ましいという認識が高まりました。これは、ユーザーがGoのツールをより発見しやすく、使いやすくするためです。go tool
サブコマンドの導入は、Goのビルドシステムとツール管理を整理し、将来的なツールの追加や管理を容易にするための重要なステップでした。このコミットは、その再編の一環として、特に利用頻度の高い fix
と vet
を go tool
の傘下に収めることを目的としています。
前提知識の解説
gofix
/fix
: Go言語のバージョンアップに伴うAPIの変更や言語仕様の変更に対応するため、既存のGoソースコードを自動的に修正するツールです。例えば、Go 1からGo 1.1への移行時に、特定の関数のシグネチャが変更された場合などに、gofix
を実行することでコードを新しいAPIに適合させることができました。このコミット以降はgo tool fix
として利用されます。govet
/vet
: Go言語の静的解析ツールです。コードを実行せずに、潜在的なバグや疑わしいコードパターン(例:Printf
のフォーマット文字列と引数の不一致、到達不能なコードなど)を検出します。開発者がコードレビューやテストの前に問題を特定するのに役立ちます。このコミット以降はgo tool vet
として利用されます。go tool
: Go 1.0以降に導入された、Go言語の補助ツールを実行するためのコマンドです。go build
やgo run
といった主要なコマンドとは異なり、go tool
はコンパイラ、リンカ、アセンブラ、プロファイラ、静的解析ツールなど、Goの内部的な開発ツールや、あまり頻繁には使われないが開発に役立つツール群へのアクセスを提供します。これにより、Goのツール群がgo
コマンドの下に一元的に管理され、ユーザーはgo tool <toolname>
の形式でこれらのツールを実行できるようになりました。GOROOT
: Goのインストールディレクトリを指す環境変数です。Goの標準ライブラリ、ツール、ドキュメントなどがこのディレクトリ以下に配置されます。GOROOT/bin/go-tool
: このコミットで導入された、go tool
コマンドで実行される補助ツールがインストールされる新しいディレクトリパスです。これにより、主要なgo
コマンド(go build
,go run
など)がインストールされるGOROOT/bin
とは別に、補助ツールが管理されるようになります。
技術的詳細
このコミットの技術的な核心は、Goのビルドシステムとツールパスの管理方法の変更にあります。
-
ファイルのリネーム:
src/cmd/gofix
ディレクトリとその配下のすべてのファイルがsrc/cmd/fix
にリネームされました。src/cmd/govet
ディレクトリとその配下のすべてのファイルがsrc/cmd/vet
にリネームされました。- これに伴い、各ツールの
doc.go
ファイルの内容も更新され、新しいコマンド名 (fix
,vet
) とgo tool
を使用した呼び出し方法が明記されました。 main.go
ファイル内のデバッグメッセージや一時ファイル名も、新しいツール名に合わせて変更されています。
-
Makefileの更新:
src/cmd/Makefile
およびsrc/pkg/Makefile
において、gofix
とgovet
への参照がfix
とvet
に更新されました。- 特に
src/cmd/gofix/Makefile
とsrc/cmd/govet/Makefile
は、それぞれsrc/cmd/fix/Makefile
とsrc/cmd/vet/Makefile
にリネームされ、ビルドターゲット名 (TARG
) やインクルードするMakefile (Make.cmd
からMake.tool
) が変更されました。Make.tool
は、go tool
コマンドで実行されるツール向けの共通Makefileインクルードファイルであり、これらのツールがGOROOT/bin/go-tool
にインストールされることを示唆しています。
-
cmd/go/pkg.go
の変更:- このファイルは
go
コマンドがパッケージをスキャンし、ビルドターゲットを決定するロジックを含んでいます。 isGoTool
という新しいマップが導入されました。このマップは、go tool
コマンドで実行されるべきツール(cmd/fix
,cmd/vet
,cmd/yacc
)のインポートパスを保持します。scanPackage
関数内で、パッケージのターゲットパスを決定するロジックが変更されました。- もしパッケージが
main
パッケージであり、かつGOROOT
内のツールであり、isGoTool
マップに登録されている場合、そのツールのインストールパスはGOROOT/bin/go-tool/<toolname>
となります。 - それ以外の場合(通常の実行可能ファイルなど)は、引き続き
GOROOT/bin/<toolname>
またはGOPATH/bin/<toolname>
にインストールされます。
- もしパッケージが
- この変更により、
fix
やvet
といった補助ツールが、主要なgo
コマンドとは別の専用ディレクトリに配置されるようになり、go tool
コマンドを通じてのみ実行されるという意図が明確化されました。
- このファイルは
-
cmd/go/fix.go
およびcmd/go/vet.go
の変更:- これらのファイルは、
go fix
およびgo vet
コマンドのラッパーとして機能します。 UsageLine
やLong
フィールドが更新され、ユーザーに対してgo tool fix
やgo tool vet
を直接実行するよう促すメッセージが追加されました。これは、go fix
やgo vet
が内部的にgo tool fix
やgo tool vet
を呼び出すことを示唆しており、ユーザーが直接go tool
を使うことで、より詳細なオプションを渡せることを示しています。
- これらのファイルは、
これらの変更は、Goのビルドシステムとツールの配布方法における重要な構造的改善であり、Go 1.0のリリースに向けた最終的な整理の一環として行われました。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、src/cmd/go/pkg.go
における isGoTool
マップの導入と、それに基づくツールのインストールパス決定ロジックの変更です。
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -224,6 +224,14 @@ Loop:
return string(b)
}
+// isGoTool is the list of directories for Go programs that are installed in
+// $GOROOT/bin/go-tool.
+var isGoTool = map[string]bool{
+ "cmd/fix": true,
+ "cmd/vet": true,
+ "cmd/yacc": true,
+}
+
func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string, stk *importStack) *Package {
// Read the files in the directory to learn the structure
// of the package.
@@ -262,7 +270,11 @@ func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string
if info.Package == "main" {
_, elem := filepath.Split(importPath)
- p.target = filepath.Join(t.BinDir(), elem)
+ if t.Goroot && isGoTool[p.ImportPath] {
+ p.target = filepath.Join(t.Path, "bin/go-tool", elem)
+ } else {
+ p.target = filepath.Join(t.BinDir(), elem)
+ }
if ctxt.GOOS == "windows" {
p.target += ".exe"
}
また、src/cmd/fix/doc.go
の新規追加も重要です。これは fix
コマンドの公式ドキュメントとなり、go tool fix
としての利用方法を明確に示しています。
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Fix finds Go programs that use old APIs and rewrites them to use
newer ones. After you update to a new Go release, fix helps make
the necessary changes to your programs.
Usage:
go tool fix [-r name,...] [path ...]
Without an explicit path, fix reads standard input and writes the
result to standard output.
If the named path is a file, fix rewrites the named files in place.
If the named path is a directory, fix rewrites all .go files in that
directory tree. When fix rewrites a file, it prints a line to standard
error giving the name of the file and the rewrite applied.
If the -diff flag is set, no files are rewritten. Instead fix prints
the differences a rewrite would introduce.
The -r flag restricts the set of rewrites considered to those in the
named list. By default fix considers all known rewrites. Fix's
rewrites are idempotent, so that it is safe to apply fix to updated
or partially updated code even without using the -r flag.
Fix prints the full list of fixes it can apply in its help output;
to see them, run go tool fix -?.
Fix does not make backup copies of the files that it edits.
Instead, use a version control system's ``diff'' functionality to inspect
the changes that fix makes before committing them.
*/
package documentation
コアとなるコードの解説
src/cmd/go/pkg.go
の変更は、Goのビルドシステムが実行可能ファイルをどこに配置するかを制御する中心的なロジックに影響を与えます。
isGoTool
マップ: このマップは、Goのソースツリー内でcmd/fix
,cmd/vet
,cmd/yacc
といった特定のインポートパスを持つパッケージが、通常の実行可能ファイルとは異なる特別なツールとして扱われるべきであることを示します。- ターゲットパスの決定ロジック:
scanPackage
関数内で、ビルドされるパッケージがmain
パッケージ(つまり実行可能ファイル)である場合に、そのインストール先パス (p.target
) が決定されます。t.Goroot
は、現在処理しているパッケージがGOROOT
内にあるかどうかを示します。isGoTool[p.ImportPath]
は、そのパッケージがgo tool
コマンドで実行されるべき補助ツールであるかどうかをチェックします。- もし両方の条件が真であれば、ツールは
GOROOT/bin/go-tool/<toolname>
にインストールされます。これは、これらのツールがGoの内部的な補助ツールであり、通常のユーザーが直接パスを通して実行するのではなく、go tool
コマンドを介して実行することを意図しているためです。 - それ以外の場合、実行可能ファイルは
t.BinDir()
(通常はGOROOT/bin
またはGOPATH/bin
) にインストールされます。
この変更により、Goのツール群の構造が明確化され、主要な go
コマンドと補助ツールが論理的に分離されました。ユーザーは go build
でビルドした自身のプログラムを GOROOT/bin
や GOPATH/bin
に配置し、Goの公式ツールは go tool
を介して利用するという、より整理されたワークフローが確立されました。
src/cmd/fix/doc.go
は、fix
コマンドの新しい公式ドキュメントとして機能します。このドキュメントは、fix
の目的、使用方法、オプション、および go tool fix
として実行することの重要性を明確に説明しています。特に、go tool fix -?
を実行することで利用可能な修正の一覧が表示されることや、バージョン管理システムと組み合わせて変更を検査することの推奨事項は、ユーザーが fix
を安全かつ効果的に利用するための重要な情報です。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
go tool
コマンドに関する情報: https://go.dev/cmd/go/#hdr-Go_tool_commandsfix
コマンドのドキュメント: https://go.dev/cmd/fix/vet
コマンドのドキュメント: https://go.dev/cmd/vet/
参考にした情報源リンク
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go Code Review (Gerrit): https://go-review.googlesource.com/ (コミットメッセージに記載されている
https://golang.org/cl/5595044
はGerritの変更リストへのリンクです) - Go言語のIssue Tracker: https://go.dev/issue
- Go言語のブログ (過去のリリース情報やツールの紹介): https://go.dev/blog/
- Go 1 Release Notes (
go tool
の導入など): https://go.dev/doc/go1 - Goのツールに関する議論や設計ドキュメント (Goのメーリングリストやデザインドキュメント): 検索キーワード "Go
go tool
design", "Gogofix
govet
rename" など。- 特に、Go 1のリリースに向けたツールの整理に関する議論は、Goのメーリングリストアーカイブやデザインドキュメントに多く見られます。