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

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

このコミットは、Go言語の公式リポジトリにおける、misc/bash/go スクリプトの変更に関するものです。具体的には、Bashシェルにおけるgoコマンドの補完機能に、新たにgo envコマンドを追加する修正を行っています。これにより、ユーザーがBash環境でgo envと入力する際に、コマンドの自動補完が効くようになります。

コミット

commit 2940dd4bf416322011182a7f8d8d5706932db61f
Author: Rui Ueyama <ruiu@google.com>
Date:   Mon Mar 17 11:58:02 2014 -0700

    misc/bash/go: Add a completion rule for "go env".
    
    "env" is a valid go command. This patch is to make bash to autocomplete it.
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/74660045

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

https://github.com/golang/go/commit/2940dd4bf416322011182a7f8d8d5706932db61f

元コミット内容

misc/bash/go: Add a completion rule for "go env".

"env" is a valid go command. This patch is to make bash to autocomplete it.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/74660045

変更の背景

Go言語のコマンドラインツールには、go buildgo rungo testなど、様々なサブコマンドが存在します。これらのサブコマンドは、開発者が効率的に作業を進める上で非常に重要です。Bashなどのシェル環境では、コマンドの自動補完機能(タブ補完)が提供されており、これによりユーザーはコマンドの一部を入力するだけで、残りの部分を自動的に補完させることができます。これは、入力の手間を省き、タイプミスを減らす上で非常に役立ちます。

このコミットが行われた当時、go envコマンドは既にGoツールチェインの一部として存在し、有効なコマンドでした。しかし、Go言語の公式リポジトリに含まれるBash補完スクリプト(misc/bash/go)には、このgo envコマンドが補完対象として含まれていませんでした。そのため、ユーザーがgo envと入力しようとした際に、タブ補完が機能せず、手動でコマンド全体を入力する必要がありました。

このコミットの目的は、この不便を解消し、go envコマンドも他の主要なgoサブコマンドと同様にBashの自動補完の恩恵を受けられるようにすることでした。これにより、Go開発者のコマンドライン操作の利便性が向上します。

前提知識の解説

1. Go言語のgoコマンド

Go言語には、ソースコードのビルド、テスト、実行、パッケージ管理など、様々な開発タスクを統合的に管理するためのgoコマンドラインツールが用意されています。このgoコマンドは、その後に続くサブコマンド(例: build, run, test, get, fmtなど)によって具体的な動作が決定されます。

2. go envコマンド

go envコマンドは、Go言語の環境変数に関する情報を表示するために使用されます。例えば、GOPATHGOROOTGOOSGOARCHなどの重要な環境変数の現在の設定値を確認することができます。これらの環境変数は、Goのビルドプロセスやパッケージの探索パスなどに影響を与えるため、開発者が自身のGo環境を理解し、デバッグする上で不可欠なツールです。

3. Bashの自動補完 (Programmable Completion)

Bash(Bourne-Again SHell)は、LinuxなどのUnix系OSで広く使われているシェルです。Bashには「プログラマブル補完 (Programmable Completion)」という強力な機能があり、これによりユーザーは特定のコマンドに対してカスタムの補完ルールを定義できます。

この機能は、completeコマンドと、補完ロジックを記述したシェルスクリプト(通常は_で始まる関数名を持つ)を組み合わせて実現されます。例えば、_goという関数がgoコマンドの補完ロジックを定義し、complete -F _go goのように設定することで、goコマンドの後にタブを押した際に_go関数が呼び出され、適切な補完候補が提示されるようになります。

補完スクリプト内では、COMP_WORDS(現在入力されているコマンドラインの単語の配列)やCOMP_CWORD(現在のカーソル位置の単語のインデックス)などの特殊なシェル変数を利用して、ユーザーの入力状況を判断し、適切な補完候補(COMPREPLY変数に設定)を生成します。

4. misc/bash/goスクリプト

Go言語の公式リポジトリには、misc/bash/goというファイルが存在します。これは、GoコマンドのBash補完機能を提供するためのシェルスクリプトです。このスクリプトは、Goのインストール時にシステムに配置されるか、ユーザーが手動で読み込むことで、Bashシェルでgoコマンドのサブコマンドやフラグの補完を有効にします。

このスクリプトの内部では、_goという関数が定義されており、この関数がgoコマンドの補完ロジックを実装しています。具体的には、goコマンドの後に続くサブコマンドのリストを保持し、ユーザーの入力に応じてそのリストから適切な候補をフィルタリングして提示します。

技術的詳細

このコミットの技術的な変更は非常にシンプルですが、Bashのプログラマブル補完の仕組みを理解する上で良い例となります。

misc/bash/goスクリプトの核心は、_go関数内に定義されているcmds変数です。この変数には、goコマンドがサポートする主要なサブコマンドのリストが文字列として格納されています。Bashの補完機能は、このcmds変数に列挙された文字列を基に、ユーザーが入力した内容と前方一致する候補を提示します。

変更前は、cmds変数にenvが含まれていなかったため、go enと入力してタブを押してもenvが補完候補として表示されませんでした。

このコミットでは、単にこのcmds変数にenvという文字列を追加することで、go envコマンドが補完対象となるように修正しています。

Bashの補完スクリプトは、通常、以下のようなロジックで動作します。

  1. ユーザーがコマンドとスペース、そして補完したい文字列の一部を入力し、タブキーを押す。
  2. Bashは、そのコマンドに紐付けられた補完関数(この場合は_go)を呼び出す。
  3. 補完関数内では、COMP_WORDS配列(入力された単語のリスト)とCOMP_CWORD(現在のカーソル位置の単語のインデックス)を使って、ユーザーがどの位置で何を補完しようとしているかを判断する。
  4. このコミットの場合、goコマンドの直後のサブコマンドを補完しようとしているため、COMP_WORDS[1](2番目の単語、つまりサブコマンド)が対象となる。
  5. 補完関数は、定義済みのサブコマンドリスト(cmds変数)から、COMP_WORDS[1]と前方一致するものをフィルタリングする。
  6. フィルタリングされた結果がCOMPREPLY変数に格納され、Bashがそれをユーザーに提示する。

このコミットは、このcmdsリストにenvを追加することで、ステップ5のフィルタリングプロセスでenvが候補として含まれるようにしています。

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

変更は、misc/bash/goファイル内の1箇所のみです。

--- a/misc/bash/go
+++ b/misc/bash/go
@@ -20,7 +20,7 @@ _go()
 
   local cmd="${COMP_WORDS[1]}"
 
-  local cmds="build clean doc fix fmt get
+  local cmds="build clean env doc fix fmt get
     install list run test tool version vet"
   local addhelp="gopath importpath remote
     testflag testfunc"

コアとなるコードの解説

変更された行は、_go関数内のcmds変数の定義です。

変更前: local cmds="build clean doc fix fmt get install list run test tool version vet"

変更後: local cmds="build clean env doc fix fmt get install list run test tool version vet"

この変更により、cmdsというローカル変数に格納されているgoコマンドのサブコマンドのリストに、新たにenvが追加されました。このcmds変数は、Bashの補完機能が利用する候補リストの元となるものです。

_go関数は、ユーザーがgoコマンドを入力した後にタブキーを押した際に呼び出されます。この関数内で、COMP_WORDS配列(ユーザーが入力したコマンドラインの単語を格納)の2番目の要素(COMP_WORDS[1])が、補完対象のサブコマンドとして取得されます。その後、このcmds変数に含まれる文字列とCOMP_WORDS[1]を比較し、前方一致するものを補完候補として提示します。

envがこのリストに追加されたことで、例えばユーザーがgo enと入力してタブを押すと、envが補完候補として表示されるようになります。これは、Bashのcompgenコマンドや、内部的な文字列比較ロジックによって実現されます。

この修正は、Goのツールチェインの機能そのものには影響を与えませんが、Go開発者のコマンドラインでの操作性を向上させる、純粋な利便性のための改善です。

関連リンク

参考にした情報源リンク

  • Go言語の公式リポジトリ (GitHub): https://github.com/golang/go
  • Go Code Review (Gerrit): https://go-review.googlesource.com/ (コミットメッセージに記載されているhttps://golang.org/cl/74660045は、Goプロジェクトが利用しているGerritの変更リストへのリンクです。)
  • Bashの補完に関する一般的な情報源 (例: man bashProgrammable Completionセクション、オンラインのBashチュートリアルなど)