Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15015] ファイルの概要

このコミットは、Goコマンドラインツール(cmd/go)において、バージョン管理システム(VCS)のコマンドが見つからない場合に、より分かりやすいエラーメッセージを追加するものです。具体的には、go getなどのコマンドが内部で利用するgithg(Mercurial)といったVCSツールがシステムにインストールされていない、またはパスが通っていない場合に、ユーザーに適切な情報を提供するように改善されています。

コミット

commit 56517aed959d2f73e7d76e80c79c5cbc87e4bd54
Author: Gustavo Franco <gustavorfranco@gmail.com>
Date:   Tue Jan 29 08:20:43 2013 -0800

    cmd/go: add helpful error message when vcs is not found.
    Fixes #4652.
    
    R=bradfitz, minux.ma, rsc
    CC=golang-dev
    https://golang.org/cl/7094049

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/56517aed959d2f73e7d76e80c79c5cbc87e4bd54

元コミット内容

cmd/go: vcsが見つからない場合に役立つエラーメッセージを追加。 Fixes #4652.

R=bradfitz, minux.ma, rsc CC=golang-dev https://golang.org/cl/7094049

変更の背景

この変更は、GoのIssue #4652を解決するために行われました。Goのgo getコマンドは、指定されたパッケージのソースコードをリモートリポジトリから取得するために、内部的にGitやMercurial(hg)などのバージョン管理システム(VCS)ツールを利用します。しかし、これらのVCSツールがユーザーのシステムにインストールされていない、または実行パスが正しく設定されていない場合、go getコマンドは単に「コマンドが見つかりません」といった一般的なエラーを返すだけでした。

このような一般的なエラーメッセージでは、ユーザーは何が問題で、どのように解決すれば良いのかを理解するのが困難でした。特にGoを初めて使うユーザーにとっては、VCSツールのインストールが必要であるという前提が分かりにくく、Goの利用開始の障壁となっていました。このコミットは、このユーザーエクスペリエンスの課題を解決し、VCSツールが見つからない場合に、より具体的で役立つエラーメッセージと、解決策へのリンク(http://golang.org/s/gogetcmd)を提示することで、ユーザーが問題を迅速に特定し、解決できるようにすることを目的としています。

前提知識の解説

Goコマンド (cmd/go)

cmd/goは、Go言語の公式ツールチェーンに含まれる主要なコマンドラインツールです。Goプログラムのビルド、テスト、インストール、依存関係の管理など、Go開発における様々なタスクを実行します。特にgo getコマンドは、リモートリポジトリからGoパッケージを取得し、依存関係を解決するために広く利用されます。

バージョン管理システム (VCS)

バージョン管理システム(Version Control System, VCS)は、ソフトウェア開発においてソースコードやその他のファイルの変更履歴を管理するためのシステムです。代表的なVCSにはGit、Mercurial (hg)、Subversion (svn) などがあります。go getコマンドは、GitHubやBitbucketなどのVCSホスティングサービスからコードを取得する際に、これらのVCSツールをバックエンドとして利用します。

exec.LookPath

Go言語の標準ライブラリos/execパッケージに含まれるLookPath関数は、指定された実行可能ファイルがシステムのPATH環境変数で指定されたディレクトリ内に存在するかどうかを検索します。ファイルが見つかった場合はその絶対パスを返し、見つからない場合はエラーを返します。このコミットでは、go getがVCSコマンドを実行する前に、そのコマンドがシステム上で利用可能かどうかを確認するためにexec.LookPathが使用されています。

fmt.Fprintfos.Stderr

fmt.Fprintfは、指定されたio.Writerにフォーマットされた文字列を書き込む関数です。os.Stderrは、標準エラー出力(Standard Error)を表すio.Writerです。プログラムがエラーメッセージや診断情報を出力する際に使用されます。このコミットでは、VCSコマンドが見つからないというエラーメッセージをユーザーの標準エラー出力に表示するために利用されています。

GoのIssueトラッカー (Fixes #4652)

Goプロジェクトは、GitHubのIssueトラッカー(または以前のGoの独自のIssueトラッカー)を使用してバグ報告や機能リクエストを管理しています。コミットメッセージに含まれるFixes #4652という記述は、このコミットがIssue番号4652で報告された問題を解決することを示しています。これにより、コミットと関連するIssueが紐付けられ、変更の目的が明確になります。

golang.org/s/gogetcmd

これはGoプロジェクトが提供する短縮URLです。このURLにアクセスすると、go getコマンドがVCSツールを見つけられない場合の対処法について説明されたドキュメントページにリダイレクトされます。このコミットによって、ユーザーはエラーメッセージから直接このヘルプページにアクセスできるようになり、問題解決が容易になります。

技術的詳細

このコミットの技術的な変更は、src/cmd/go/vcs.goファイルのvcsCmd構造体のrun1メソッド内で行われています。

run1メソッドは、特定のVCSコマンド(例: git clone, hg pull)を実行するための内部ヘルパー関数です。変更前は、このメソッドはVCSコマンドの実行を直接試み、コマンドが見つからない場合はexec.Commandが返すエラーをそのまま伝播していました。このエラーは通常、"executable file not found in $PATH"のような一般的なメッセージでした。

変更後、exec.Commandを呼び出す前に、exec.LookPath(v.cmd)が追加されました。

  1. v.cmdは、実行しようとしているVCSコマンドの名前(例: "git", "hg")を保持しています。
  2. exec.LookPathは、このコマンドがシステムの実行パス(PATH環境変数)上で見つかるかどうかを確認します。
  3. もしexec.LookPathがエラーを返した場合(つまり、コマンドが見つからない場合)、新しいエラーハンドリングロジックが実行されます。
    • fmt.Fprintf(os.Stderr, "go: missing %s command. See http://golang.org/s/gogetcmd\\n", v.name)という行が追加され、より具体的で役立つエラーメッセージが標準エラー出力に表示されます。v.nameはVCSの名前(例: "git", "mercurial")です。
    • その後、return nil, errによって、LookPathが返した元のエラーが呼び出し元に伝播されます。これにより、Goツールチェーンの他の部分がこのエラーを適切に処理できるようになります。

また、既存のerr := cmd.Run()の行がerr = cmd.Run()に変更されています。これは、exec.LookPathの呼び出しでerr変数が既に宣言されているため、再宣言ではなく代入を行うように修正されたものです。

この変更により、VCSコマンドが見つからないという特定のエラーケースに対して、Goツールがよりユーザーフレンドリーな診断情報を提供できるようになりました。

コアとなるコードの変更箇所

変更はsrc/cmd/go/vcs.goファイル内のvcsCmd構造体のrun1メソッドに集中しています。

--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -180,6 +180,14 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
 		args[i] = expand(m, arg)
 	}
 
+	_, err := exec.LookPath(v.cmd)
+	if err != nil {
+		fmt.Fprintf(os.Stderr,
+			"go: missing %s command. See http://golang.org/s/gogetcmd\\n",
+			v.name)
+		return nil, err
+	}
+
 	cmd := exec.Command(v.cmd, args...)
 	cmd.Dir = dir
 	if buildX {
@@ -189,7 +197,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
 	var buf bytes.Buffer
 	cmd.Stdout = &buf
 	cmd.Stderr = &buf
-	err := cmd.Run()
+	err = cmd.Run()
 	out := buf.Bytes()
 	if err != nil {
 		if verbose || buildV {

コアとなるコードの解説

追加されたコード

	_, err := exec.LookPath(v.cmd)
	if err != nil {
		fmt.Fprintf(os.Stderr,
			"go: missing %s command. See http://golang.org/s/gogetcmd\\n",
			v.name)
		return nil, err
	}
  • _, err := exec.LookPath(v.cmd): ここで、v.cmd(例: "git"や"hg")で指定されたVCSコマンドがシステムの実行パス(PATH環境変数)上に存在するかどうかをexec.LookPath関数を使って確認しています。結果はerr変数に格納されます。_は、関数の最初の戻り値(コマンドの絶対パス)がこの時点では不要なため破棄していることを示します。
  • if err != nil: LookPathがエラーを返した場合、それはVCSコマンドが見つからなかったことを意味します。
  • fmt.Fprintf(os.Stderr, ...): この行が、ユーザーに表示される新しいエラーメッセージを生成します。
    • os.Stderr: エラーメッセージを標準エラー出力に書き込むことを指定します。
    • "go: missing %s command. See http://golang.org/s/gogetcmd\\n": フォーマット文字列です。%sv.name(VCSの名前、例: "git")に置き換えられます。これにより、「go: missing git command. See http://golang.org/s/gogetcmd」のようなメッセージが出力されます。
    • v.name: 現在処理しているVCSの名前(例: "git", "mercurial")です。
  • return nil, err: エラーメッセージを出力した後、LookPathが返した元のエラーをrun1メソッドの呼び出し元に返します。これにより、Goツールチェーンのより上位の層でエラーが適切に処理され、最終的にユーザーにエラーが報告されます。

変更されたコード

-	err := cmd.Run()
+	err = cmd.Run()
  • err := cmd.Run()からerr = cmd.Run()への変更は、Go言語における変数のスコープと宣言のルールによるものです。
  • 変更前は、cmd.Run()の戻り値であるエラーを新しい変数errに代入していました。
  • しかし、追加された_, err := exec.LookPath(v.cmd)の行で、既にerrという名前の変数がこの関数のスコープ内で宣言されています。
  • Goでは、同じスコープ内で同じ名前の変数を:=(短い変数宣言)を使って再宣言することはできません。そのため、既に宣言されているerr変数に値を再代入するために、=演算子を使用するように修正されました。

この一連の変更により、GoツールはVCSコマンドの存在を事前にチェックし、見つからない場合にはユーザーに具体的なガイダンスを提供できるようになり、デバッグの労力を大幅に削減します。

関連リンク

参考にした情報源リンク

  • golang.org/s/gogetcmd の内容(Web検索結果に基づく):この短縮URLは、Goの公式ドキュメントの「Go Command: go get」セクション、特にVCSツールのインストールに関する部分にリダイレクトされます。例えば、GitやMercurialのインストール方法、PATH環境変数の設定方法などが説明されています。
  • Go言語のos/execパッケージのドキュメント: https://pkg.go.dev/os/exec
  • Go言語のfmtパッケージのドキュメント: https://pkg.go.dev/fmt
  • Go言語のosパッケージのドキュメント(os.Stderrについて): https://pkg.go.dev/os
  • Go言語の短い変数宣言(:=)と通常の代入(=)に関する情報(Go言語のチュートリアルや公式ドキュメント全般)

[インデックス 15015] ファイルの概要

このコミットは、Goコマンドラインツール(cmd/go)において、バージョン管理システム(VCS)のコマンドが見つからない場合に、より分かりやすいエラーメッセージを追加するものです。具体的には、go getなどのコマンドが内部で利用するgithg(Mercurial)といったVCSツールがシステムにインストールされていない、またはパスが通っていない場合に、ユーザーに適切な情報を提供するように改善されています。

コミット

commit 56517aed959d2f73e7d76e80c79c5cbc87e4bd54
Author: Gustavo Franco <gustavorfranco@gmail.com>
Date:   Tue Jan 29 08:20:43 2013 -0800

    cmd/go: add helpful error message when vcs is not found.
    Fixes #4652.
    
    R=bradfitz, minux.ma, rsc
    CC=golang-dev
    https://golang.org/cl/7094049

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/56517aed959d2f73e7d76e80c79c5cbc87e4bd54

元コミット内容

cmd/go: vcsが見つからない場合に役立つエラーメッセージを追加。 Fixes #4652.

R=bradfitz, minux.ma, rsc CC=golang-dev https://golang.org/cl/7094049

変更の背景

この変更は、GoのIssue #4652を解決するために行われました。Goのgo getコマンドは、指定されたパッケージのソースコードをリモートリポジトリから取得するために、内部的にGitやMercurial(hg)などのバージョン管理システム(VCS)ツールを利用します。しかし、これらのVCSツールがユーザーのシステムにインストールされていない、または実行パスが正しく設定されていない場合、go getコマンドは単に「コマンドが見つかりません」といった一般的なエラーを返すだけでした。

このような一般的なエラーメッセージでは、ユーザーは何が問題で、どのように解決すれば良いのかを理解するのが困難でした。特にGoを初めて使うユーザーにとっては、VCSツールのインストールが必要であるという前提が分かりにくく、Goの利用開始の障壁となっていました。このコミットは、このユーザーエクスペリエンスの課題を解決し、VCSツールが見つからない場合に、より具体的で役立つエラーメッセージと、解決策へのリンク(http://golang.org/s/gogetcmd)を提示することで、ユーザーが問題を迅速に特定し、解決できるようにすることを目的としています。

前提知識の解説

Goコマンド (cmd/go)

cmd/goは、Go言語の公式ツールチェーンに含まれる主要なコマンドラインツールです。Goプログラムのビルド、テスト、インストール、依存関係の管理など、Go開発における様々なタスクを実行します。特にgo getコマンドは、リモートリポジトリからGoパッケージを取得し、依存関係を解決するために広く利用されます。

バージョン管理システム (VCS)

バージョン管理システム(Version Control System, VCS)は、ソフトウェア開発においてソースコードやその他のファイルの変更履歴を管理するためのシステムです。代表的なVCSにはGit、Mercurial (hg)、Subversion (svn) などがあります。go getコマンドは、GitHubやBitbucketなどのVCSホスティングサービスからコードを取得する際に、これらのVCSツールをバックエンドとして利用します。

exec.LookPath

Go言語の標準ライブラリos/execパッケージに含まれるLookPath関数は、指定された実行可能ファイルがシステムのPATH環境変数で指定されたディレクトリ内に存在するかどうかを検索します。ファイルが見つかった場合はその絶対パスを返し、見つからない場合はエラーを返します。このコミットでは、go getがVCSコマンドを実行する前に、そのコマンドがシステム上で利用可能かどうかを確認するためにexec.LookPathが使用されています。

fmt.Fprintfos.Stderr

fmt.Fprintfは、指定されたio.Writerにフォーマットされた文字列を書き込む関数です。os.Stderrは、標準エラー出力(Standard Error)を表すio.Writerです。プログラムがエラーメッセージや診断情報を出力する際に使用されます。このコミットでは、VCSコマンドが見つからないというエラーメッセージをユーザーの標準エラー出力に表示するために利用されています。

GoのIssueトラッカー (Fixes #4652)

Goプロジェクトは、GitHubのIssueトラッカー(または以前のGoの独自のIssueトラッカー)を使用してバグ報告や機能リクエストを管理しています。コミットメッセージに含まれるFixes #4652という記述は、このコミットがIssue番号4652で報告された問題を解決することを示しています。これにより、コミットと関連するIssueが紐付けられ、変更の目的が明確になります。

golang.org/s/gogetcmd

これはGoプロジェクトが提供する短縮URLです。このURLにアクセスすると、go getコマンドがVCSツールを見つけられない場合の対処法について説明されたドキュメントページにリダイレクトされます。このコミットによって、ユーザーはエラーメッセージから直接このヘルプページにアクセスできるようになり、問題解決が容易になります。

技術的詳細

このコミットの技術的な変更は、src/cmd/go/vcs.goファイルのvcsCmd構造体のrun1メソッド内で行われています。

run1メソッドは、特定のVCSコマンド(例: git clone, hg pull)を実行するための内部ヘルパー関数です。変更前は、このメソッドはVCSコマンドの実行を直接試み、コマンドが見つからない場合はexec.Commandが返すエラーをそのまま伝播していました。このエラーは通常、"executable file not found in $PATH"のような一般的なメッセージでした。

変更後、exec.Commandを呼び出す前に、exec.LookPath(v.cmd)が追加されました。

  1. v.cmdは、実行しようとしているVCSコマンドの名前(例: "git", "hg")を保持しています。
  2. exec.LookPathは、このコマンドがシステムの実行パス(PATH環境変数)上で見つかるかどうかを確認します。
  3. もしexec.LookPathがエラーを返した場合(つまり、コマンドが見つからない場合)、新しいエラーハンドリングロジックが実行されます。
    • fmt.Fprintf(os.Stderr, "go: missing %s command. See http://golang.org/s/gogetcmd\\n", v.name)という行が追加され、より具体的で役立つエラーメッセージが標準エラー出力に表示されます。v.nameはVCSの名前(例: "git", "mercurial")です。
    • その後、return nil, errによって、LookPathが返した元のエラーが呼び出し元に伝播されます。これにより、Goツールチェーンの他の部分がこのエラーを適切に処理できるようになります。

また、既存のerr := cmd.Run()の行がerr = cmd.Run()に変更されています。これは、exec.LookPathの呼び出しでerr変数が既に宣言されているため、再宣言ではなく代入を行うように修正されたものです。

この変更により、VCSコマンドが見つからないという特定のエラーケースに対して、Goツールがよりユーザーフレンドリーな診断情報を提供できるようになりました。

コアとなるコードの変更箇所

変更はsrc/cmd/go/vcs.goファイル内のvcsCmd構造体のrun1メソッドに集中しています。

--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -180,6 +180,14 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
 		args[i] = expand(m, arg)
 	}
 
+	_, err := exec.LookPath(v.cmd)
+	if err != nil {
+		fmt.Fprintf(os.Stderr,
+			"go: missing %s command. See http://golang.org/s/gogetcmd\\n",
+			v.name)
+		return nil, err
+	}
+
 	cmd := exec.Command(v.cmd, args...)
 	cmd.Dir = dir
 	if buildX {
@@ -189,7 +197,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
 	var buf bytes.Buffer
 	cmd.Stdout = &buf
 	cmd.Stderr = &buf
-	err := cmd.Run()
+	err = cmd.Run()
 	out := buf.Bytes()
 	if err != nil {
 		if verbose || buildV {

コアとなるコードの解説

追加されたコード

	_, err := exec.LookPath(v.cmd)
	if err != nil {
		fmt.Fprintf(os.Stderr,
			"go: missing %s command. See http://golang.org/s/gogetcmd\\n",
			v.name)
		return nil, err
	}
  • _, err := exec.LookPath(v.cmd): ここで、v.cmd(例: "git"や"hg")で指定されたVCSコマンドがシステムの実行パス(PATH環境変数)上に存在するかどうかをexec.LookPath関数を使って確認しています。結果はerr変数に格納されます。_は、関数の最初の戻り値(コマンドの絶対パス)がこの時点では不要なため破棄していることを示します。
  • if err != nil: LookPathがエラーを返した場合、それはVCSコマンドが見つからなかったことを意味します。
  • fmt.Fprintf(os.Stderr, ...): この行が、ユーザーに表示される新しいエラーメッセージを生成します。
    • os.Stderr: エラーメッセージを標準エラー出力に書き込むことを指定します。
    • "go: missing %s command. See http://golang.org/s/gogetcmd\\n": フォーマット文字列です。%sv.name(VCSの名前、例: "git")に置き換えられます。これにより、「go: missing git command. See http://golang.org/s/gogetcmd」のようなメッセージが出力されます。
    • v.name: 現在処理しているVCSの名前(例: "git", "mercurial")です。
  • return nil, err: エラーメッセージを出力した後、LookPathが返した元のエラーをrun1メソッドの呼び出し元に返します。これにより、Goツールチェーンのより上位の層でエラーが適切に処理され、最終的にユーザーにエラーが報告されます。

変更されたコード

-	err := cmd.Run()
+	err = cmd.Run()
  • err := cmd.Run()からerr = cmd.Run()への変更は、Go言語における変数のスコープと宣言のルールによるものです。
  • 変更前は、cmd.Run()の戻り値であるエラーを新しい変数errに代入していました。
  • しかし、追加された_, err := exec.LookPath(v.cmd)の行で、既にerrという名前の変数がこの関数のスコープ内で宣言されています。
  • Goでは、同じスコープ内で同じ名前の変数を:=(短い変数宣言)を使って再宣言することはできません。そのため、既に宣言されているerr変数に値を再代入するために、=演算子を使用するように修正されました。

この一連の変更により、GoツールはVCSコマンドの存在を事前にチェックし、見つからない場合にはユーザーに具体的なガイダンスを提供できるようになり、デバッグの労力を大幅に削減します。

関連リンク

参考にした情報源リンク

  • golang.org/s/gogetcmd の内容(Web検索結果に基づく):この短縮URLは、Goの公式ドキュメントの「Go Command: go get」セクション、特にVCSツールのインストールに関する部分にリダイレクトされます。例えば、GitやMercurialのインストール方法、PATH環境変数の設定方法などが説明されています。
  • Go言語のos/execパッケージのドキュメント: https://pkg.go.dev/os/exec
  • Go言語のfmtパッケージのドキュメント: https://pkg.go.dev/fmt
  • Go言語のosパッケージのドキュメント(os.Stderrについて): https://pkg.go.dev/os
  • Go言語の短い変数宣言(:=)と通常の代入(=)に関する情報(Go言語のチュートリアルや公式ドキュメント全般)