[インデックス 17733] ファイルの概要
このコミットは、Go言語のコマンドラインツール go
におけるドキュメントの改善と整理を目的としています。特に、Goパッケージのインポートパスに関する説明を更新し、相対インポートパスの概念を明確にしています。
コミット
commit e0867738fc3df8fcf5ff4392e29901c87ffed115
Author: Russ Cox <rsc@golang.org>
Date: Wed Oct 2 21:42:23 2013 -0400
cmd/go: document relative imports
Fixes #3524.
R=golang-dev, iant, r
CC=golang-dev
https://golang.org/cl/14296043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e0867738fc3df8fcf5ff4392e29901c87ffed115
元コミット内容
cmd/go: document relative imports
(cmd/go
: 相対インポートをドキュメント化)
このコミットは、Goツールにおける相対インポートのドキュメントを改善することを目的としています。具体的には、Issue #3524 を修正します。
変更の背景
Go言語の初期のバージョンでは、パッケージのインポートパスに関するドキュメントが分散しており、特に相対インポートの挙動について不明瞭な点がありました。ユーザーは、go
コマンドがどのようにインポートパスを解決し、特に ./
や ../
で始まる相対パスがどのように扱われるのかについて混乱することがありました。
このコミットの背景には、以下の課題がありました。
- ドキュメントの不足と分散:
go help
コマンドで利用できるヘルプトピックの中に、インポートパスの全体像を包括的に説明するものがありませんでした。特に、相対インポートパスに関する詳細な説明が不足していました。 - 相対インポートの誤解: 相対インポートは、ワークスペース外での小規模な実験的なプログラムや、コマンドラインでのショートカットとして有用ですが、ワークスペース内での使用は推奨されず、曖昧さを避けるために禁止されています。この区別がドキュメントで明確にされていませんでした。
remote
ヘルプトピックの統合: 以前はgo help remote
という独立したヘルプトピックでリモートインポートパスについて説明されていましたが、インポートパス全体の文脈で説明されるべき内容でした。
これらの課題を解決するため、このコミットでは importpath
という新しいヘルプトピックを導入し、インポートパスに関するすべての情報を一元化し、特に相対インポートの挙動を詳細に説明することで、ユーザーの理解を深めることを目指しました。
前提知識の解説
このコミットの理解には、以下のGo言語の基本的な概念が前提となります。
-
Goパッケージとインポートパス:
- Go言語のコードは「パッケージ」という単位で整理されます。パッケージは関連する機能の集合であり、再利用可能なコードの最小単位です。
- 他のパッケージの機能を利用するには、
import
ステートメントを使ってそのパッケージをインポートします。 - インポートパスは、Goツールがパッケージのソースコードを見つけるための識別子です。通常、GitHubなどのリポジトリパスや、標準ライブラリのパス(例:
"fmt"
,"net/http"
)が使われます。
-
GOPATH:
GOPATH
は、Goのワークスペースのルートディレクトリを指定する環境変数です。Goのソースコード、コンパイル済みパッケージ、実行可能バイナリがこのディレクトリ構造内に配置されます。- Goツールは、
GOPATH
内のsrc
ディレクトリ以下にインポートパスに対応するパッケージを探します。例えば、GOPATH
が/home/user/go
で、import "github.com/user/repo/pkg"
であれば、Goツールは/home/user/go/src/github.com/user/repo/pkg
を探します。
-
go
コマンド:go
コマンドは、Go言語のソースコードのビルド、テスト、インストール、フォーマットなど、様々な開発タスクを管理するための主要なツールです。go help [topic]
コマンドは、特定のトピックに関する詳細なヘルプ情報を表示します。
-
相対インポートパス:
- Go言語では、
./
や../
で始まるインポートパスを「相対インポートパス」と呼びます。これらはファイルシステム上の相対的な位置を示します。 - コマンドラインでのショートカット:
go test ./subpkg
のように、go
コマンドの引数として相対パスを使用すると、現在のディレクトリからの相対的なパッケージを指定できます。これは、フルパスを入力する手間を省くためのショートカットとして機能します。 - ワークスペース外での使用:
GOPATH
を設定していない環境や、一時的な小規模プロジェクトで、複数のパッケージを構成する際に、import "./anotherpkg"
のように相対インポートを使用することが可能です。ただし、このようなプログラムはgo install
でインストールできません。 - ワークスペース内での制限: 曖昧さを避けるため、
GOPATH
内のワークスペースで開発されているGoプログラムでは、相対インポートパスの使用は禁止されています。これは、パッケージの絶対的なインポートパスが明確に定義されているべきであるというGoの設計思想に基づいています。
- Go言語では、
技術的詳細
このコミットの主要な変更点は、Goツールのヘルプドキュメントの再編成と内容の更新です。
-
src/cmd/go/doc.go
の変更:Additional help topics
のリストからremote
が削除され、代わりにimportpath
が追加されました。これにより、インポートパスに関する情報がimportpath
に集約されることが示唆されます。go get
コマンドの説明において、「go help remote
を参照」という記述が「go help importpath
を参照」に修正されました。Description of package lists
のセクションが、Remote import path syntax
のセクションの後に移動されました。これは、パッケージリストの説明がインポートパスの文脈でより適切に配置されるようにするためです。Remote import path syntax
のセクションがImport path syntax
に改名され、その内容が大幅に拡張されました。特に、相対インポートパス (Relative import paths
) に関する詳細な説明が追加されました。- 相対パスがコマンドラインでのショートカットとしてどのように機能するか(例:
go test ./utf8
)。 - ワークスペース外でGoプログラムをコンパイルする際に、相対パスを
import
ステートメントで使用できること。 - ワークスペース内では相対インポートパスが使用できないことの明確化。
- 相対パスがコマンドラインでのショートカットとしてどのように機能するか(例:
-
src/cmd/go/get.go
の変更:go get
コマンドのヘルプメッセージにおいて、「go help remote
を参照」が「go help importpath
を参照」に修正されました。これは、go get
がリモートリポジトリからソースコードを取得する際の挙動が、新しいimportpath
ヘルプトピックで説明されるようになったためです。
-
src/cmd/go/help.go
の変更:helpC
コマンドのShort
説明が"calling between Go and C/C++"
から"calling between Go and C"
に変更されました。これは、C++との連携に関する詳細がGoのCgoドキュメントで直接扱われるようになったため、より簡潔な表現に修正されたと考えられます。helpRemote
コマンドが削除され、代わりにhelpImportPath
コマンドが新しく定義されました。helpImportPath
のLong
フィールドに、doc.go
で追加されたImport path syntax
の詳細な説明(相対インポートパスとリモートインポートパスの両方を含む)が設定されました。
-
src/cmd/go/main.go
の変更:commands
スライスからhelpRemote
が削除され、helpImportPath
が追加されました。これにより、go help importpath
コマンドが利用可能になります。
これらの変更により、Goツールのヘルプシステムがより整理され、特にインポートパスに関するユーザーの理解が深まるように改善されました。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、主に src/cmd/go/doc.go
と src/cmd/go/help.go
に集中しています。
src/cmd/go/doc.go
(抜粋)
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -32,10 +32,10 @@ Use "go help [command]" for more information about a command.
Additional help topics:
- c calling between Go and C/C++
+ c calling between Go and C
gopath GOPATH environment variable
+ importpath import path syntax
packages description of package lists
- remote remote import path syntax
testflag description of testing flags
testfunc description of testing functions
@@ -247,7 +247,7 @@ retrieves the most recent version of the package.
For more about specifying packages, see 'go help packages'.
For more about how 'go get' finds source code to
-download, see 'go help remote'.
+download, see 'go help importpath'.
See also: go build, go install, go clean.
@@ -544,66 +544,40 @@ but new packages are always downloaded into the first directory
in the list.
-Description of package lists
--
-Many commands apply to a set of packages:
--
- go action [packages]
--
-Usually, [packages] is a list of import paths.
--
-An import path that is a rooted path or that begins with
-a . or .. element is interpreted as a file system path and
-denotes the package in that directory.
--
-Otherwise, the import path P denotes the package found in
-the directory DIR/src/P for some DIR listed in the GOPATH
-environment variable (see 'go help gopath').
--
-If no import paths are given, the action applies to the
-package in the current directory.
--
-There are three reserved names for paths that should not be used
-for packages to be built with the go tool:
--
-- "main" denotes the top-level package in a stand-alone executable.
--
-- "all" expands to all package directories found in all the GOPATH
-trees. For example, 'go list all' lists all the packages on the local
-system.
--
-- "std" is like all but expands to just the packages in the standard
-Go library.
--
-An import path is a pattern if it includes one or more "..." wildcards,
-each of which can match any string, including the empty string and
-strings containing slashes. Such a pattern expands to all package
-directories found in the GOPATH trees with names matching the
-patterns. As a special case, x/... matches x as well as x's subdirectories.
-For example, net/... expands to net and packages in its subdirectories.
--
-An import path can also name a package to be downloaded from
-a remote repository. Run 'go help remote' for details.
--
-Every package in a program must have a unique import path.
-By convention, this is arranged by starting each path with a
-unique prefix that belongs to you. For example, paths used
-internally at Google all begin with 'google', and paths
-denoting remote repositories begin with the path to the code,
-such as 'code.google.com/p/project'.
--
-As a special case, if the package list is a list of .go files from a
-single directory, the command is applied to a single synthesized
-package made up of exactly those files, ignoring any build constraints
-in those files and ignoring any other files in the directory.
--
-File names that begin with "." or "_" are ignored by the go tool.
--
--
-Remote import path syntax
+Import path syntax
An import path (see 'go help packages') denotes a package
-stored in the local file system. Certain import paths also
+stored in the local file system. In general, an import path denotes
+either a standard package (such as "unicode/utf8") or a package
+found in one of the work spaces (see 'go help gopath').
+
+Relative import paths
+
+An import path beginning with ./ or ../ is called a relative path.
+The toolchain supports relative import paths as a shortcut in two ways.
+
+First, a relative path can be used as a shorthand on the command line.
+If you are working in the directory containing the code imported as
+"unicode" and want to run the tests for "unicode/utf8", you can type
+"go test ./utf8" instead of needing to specify the full path.
+Similarly, in the reverse situation, "go test .." will test "unicode" from
+the "unicode/utf8" directory. Relative patterns are also allowed, like
+"go test ./..." to test all subdirectories. See 'go help packages' for details
+on the pattern syntax.
+
+Second, if you are compiling a Go program not in a work space,
+you can use a relative path in an import statement in that program
+to refer to nearby code also not in a work space.
+This makes it easy to experiment with small multipackage programs
+outside of the usual work spaces, but such programs cannot be
+installed with "go install" (there is no work space in which to install them),
+so they are rebuilt from scratch each time they are built.
+To avoid ambiguity, Go programs cannot use relative import paths
+within a work space.
+
+Remote import paths
+
+Certain import paths also
describe how to obtain the source code for the package using
a revision control system.
@@ -714,6 +688,62 @@ package appropriate for the Go release being used.
Run 'go help install' for more.
+Description of package lists
+
+Many commands apply to a set of packages:
+
+ go action [packages]
+
+Usually, [packages] is a list of import paths.
+
+An import path that is a rooted path or that begins with
+a . or .. element is interpreted as a file system path and
+denotes the package in that directory.
+
+Otherwise, the import path P denotes the package found in
+the directory DIR/src/P for some DIR listed in the GOPATH
+environment variable (see 'go help gopath').
+
+If no import paths are given, the action applies to the
+package in the current directory.
+
+There are three reserved names for paths that should not be used
+for packages to be built with the go tool:
+
+- "main" denotes the top-level package in a stand-alone executable.
+
+- "all" expands to all package directories found in all the GOPATH
+trees. For example, 'go list all' lists all the packages on the local
+system.
+
+- "std" is like all but expands to just the packages in the standard
+Go library.
+
+An import path is a pattern if it includes one or more "..." wildcards,
+each of which can match any string, including the empty string and
+strings containing slashes. Such a pattern expands to all package
+directories found in the GOPATH trees with names matching the
+patterns. As a special case, x/... matches x as well as x's subdirectories.
+For example, net/... expands to net and packages in its subdirectories.
+
+An import path can also name a package to be downloaded from
+a remote repository. Run 'go help importpath' for details.
+
+Every package in a program must have a unique import path.
+By convention, this is arranged by starting each path with a
+unique prefix that belongs to you. For example, paths used
+internally at Google all begin with 'google', and paths
+denoting remote repositories begin with the path to the code,
+such as 'code.google.com/p/project'.
+
+As a special case, if the package list is a list of .go files from a
+single directory, the command is applied to a single synthesized
+package made up of exactly those files, ignoring any build constraints
+in those files and ignoring any other files in the directory.
+
+File names that begin with "." or "_" are ignored by the go tool.
+
+
Description of testing flags
The 'go test' command takes both flags that apply to 'go test' itself
src/cmd/go/help.go
(抜粋)
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -6,7 +6,7 @@ package main
var helpC = &Command{
UsageLine: "c",
- Short: "calling between Go and C/C++",
+ Short: "calling between Go and C",
Long: `
There are two different ways to call between Go and C/C++ code.
@@ -67,7 +67,7 @@ patterns. As a special case, x/... matches x as well as x\'s subdirectories.
For example, net/... expands to net and packages in its subdirectories.
An import path can also name a package to be downloaded from
-a remote repository. Run 'go help remote' for details.\n
+a remote repository. Run 'go help importpath' for details.\n
Every package in a program must have a unique import path.
By convention, this is arranged by starting each path with a
@@ -85,13 +85,43 @@ File names that begin with \".\" or \"_\" are ignored by the go tool.\n \t`,\n }\n \n-var helpRemote = &Command{\n-\tUsageLine: "remote",\n-\tShort: "remote import path syntax",\n+var helpImportPath = &Command{\
+\tUsageLine: "importpath",\n+\tShort: "import path syntax",\n \tLong: `\
\n An import path (see 'go help packages') denotes a package\n-stored in the local file system. Certain import paths also\n+stored in the local file system. In general, an import path denotes\n+either a standard package (such as "unicode/utf8") or a package\n+found in one of the work spaces (see 'go help gopath').\n+\n+Relative import paths\n+\n+An import path beginning with ./ or ../ is called a relative path.\n+The toolchain supports relative import paths as a shortcut in two ways.\n+\n+First, a relative path can be used as a shorthand on the command line.\n+If you are working in the directory containing the code imported as\n+"unicode" and want to run the tests for "unicode/utf8", you can type\+"go test ./utf8" instead of needing to specify the full path.\n+Similarly, in the reverse situation, "go test .." will test "unicode" from\n+the "unicode/utf8" directory. Relative patterns are also allowed, like\n+"go test ./..." to test all subdirectories. See 'go help packages' for details\n+on the pattern syntax.\n+\n+Second, if you are compiling a Go program not in a work space,\n+you can use a relative path in an import statement in that program\n+to refer to nearby code also not in a work space.\n+This makes it easy to experiment with small multipackage programs\n+outside of the usual work spaces, but such programs cannot be\n+installed with "go install" (there is no work space in which to install them),\n+so they are rebuilt from scratch each time they are built.\n+To avoid ambiguity, Go programs cannot use relative import paths\n+within a work space.\n+\n+Remote import paths\n+\n+Certain import paths also\n describe how to obtain the source code for the package using\n a revision control system.\n \n```
## コアとなるコードの解説
このコミットの核心は、Goツールのヘルプシステムにおけるインポートパスに関する情報の整理と拡充です。
1. **`importpath` ヘルプトピックの導入**:
* 以前は `remote` というヘルプトピックでリモートインポートパスについて説明されていましたが、このコミットでは `importpath` という新しい、より包括的なヘルプトピックが導入されました。これにより、Goのインポートパスに関するすべての情報(標準パッケージ、GOPATH内のパッケージ、相対インポートパス、リモートインポートパス)が一元的に説明されるようになりました。
* `src/cmd/go/help.go` で `helpImportPath` という新しい `Command` 構造体が定義され、その `Long` フィールドに詳細な説明が記述されています。
2. **相対インポートパスの詳細な説明**:
* 最も重要な変更点は、`importpath` ヘルプトピック内に「`Relative import paths`」というセクションが追加されたことです。
* このセクションでは、相対インポートパスが以下の2つの主要なシナリオでどのように機能するかが明確に説明されています。
* **コマンドラインでのショートカット**: `go test ./subpkg` のように、`go` コマンドの引数として相対パスを使用することで、現在のディレクトリからの相対的なパッケージを簡単に指定できることが説明されています。これは、開発者が頻繁に利用する便利な機能です。
* **ワークスペース外での使用**: `GOPATH` を設定していない環境で、複数のパッケージからなる小規模な実験的なプログラムを構築する際に、`import "./anotherpkg"` のように相対インポートを使用できることが説明されています。ただし、これらのプログラムは `go install` でインストールできないという制約も明記されています。
* さらに、**「To avoid ambiguity, Go programs cannot use relative import paths within a work space.」** (曖昧さを避けるため、Goプログラムはワークスペース内で相対インポートパスを使用できません。) という重要な制約が明確に記述されました。これは、Goのパッケージ管理の堅牢性を保つ上で非常に重要なルールであり、以前のドキュメントでは十分に強調されていませんでした。
3. **ドキュメント間の参照の更新**:
* `src/cmd/go/doc.go` や `src/cmd/go/get.go` など、他のヘルプトピックやコマンドの説明から `go help remote` への参照がすべて `go help importpath` に変更されました。これにより、ユーザーはインポートパスに関する情報を探す際に、常に新しい `importpath` ヘルプトピックを参照するよう誘導されます。
これらの変更により、Goツールのドキュメントはより正確で、包括的になり、特に相対インポートパスに関するユーザーの混乱を解消するのに役立ちます。
## 関連リンク
* Go言語の公式ドキュメント: [https://go.dev/doc/](https://go.dev/doc/)
* Go Modules (現代のGoパッケージ管理): [https://go.dev/blog/using-go-modules](https://go.dev/blog/using-go-modules) (このコミットはGo Modules導入以前のものですが、現代のGo開発におけるパッケージ管理の理解に役立ちます)
* Go言語のIssue #3524: [https://github.com/golang/go/issues/3524](https://github.com/golang/go/issues/3524)
## 参考にした情報源リンク
* Go言語のソースコード (特に `src/cmd/go` ディレクトリ): [https://github.com/golang/go](https://github.com/golang/go)
* Go言語のコミット履歴: [https://github.com/golang/go/commits/master](https://github.com/golang/go/commits/master)
* Go言語の公式ブログ: [https://go.dev/blog/](https://go.dev/blog/)
* Go言語のメーリングリスト (golang-dev): [https://groups.google.com/g/golang-dev](https://groups.google.com/g/golang-dev)
* Go言語のコードレビューシステム (Gerrit): [https://go.dev/cl/](https://go.dev/cl/) (コミットメッセージに記載されている `https://golang.org/cl/14296043` は、このコミットのGerritレビューへのリンクです)
* Go言語のGOPATHに関するドキュメント: [https://go.dev/doc/code](https://go.dev/doc/code) (Go Modules導入以前のGOPATHに関する情報)
* Go言語のパッケージに関するドキュメント: [https://go.dev/doc/effective_go#packages](https://go.dev/doc/effective_go#packages)