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

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

このコミットは、Go言語の初期のビルドおよびテストスクリプトである src/run.bash に対する変更です。主な目的は、テスト実行のロジックを整理し、lib/math パッケージのテストを追加することです。

コミット

commit 5014da7cb0aeb8727b72331b627adfde410c2d3c
Author: Russ Cox <rsc@golang.org>
Date:   Thu Nov 20 10:54:11 2008 -0800

    add math to tests; clean a bit
    
    R=r
    DELTA=33  (12 added, 9 deleted, 12 changed)
    OCL=19688
    CL=19696

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

https://github.com/golang/go/commit/5014da7cb0aeb8727b72331b627adfde410c2d3c

元コミット内容

このコミットは、src/run.bash スクリプトに以下の変更を加えています。

  • lib/strconv, lib/reflect, lib/regexp のテスト実行ロジックを maketest 関数に集約。
  • lib/math のテストを maketest 関数を通じて追加。
  • コードの重複を排除し、スクリプト全体の可読性と保守性を向上。
  • ../usr/gri/pretty のテスト実行ロジックは maketest 関数に含めず、個別に実行されることを明示するコメントを追加。

変更の背景

このコミットが行われた2008年11月は、Go言語がまだ一般に公開される前の非常に初期の段階でした。当時のGoプロジェクトのビルドおよびテストプロセスは、現在のような洗練されたツールチェーン(go build, go test など)が確立されておらず、シェルスクリプトによって手動で管理されていました。

src/run.bash は、Goの様々なライブラリやコンポーネントをビルドし、テストを実行するための主要なスクリプトの一つでした。コミット前のスクリプトでは、各ライブラリ(lib/strconv, lib/reflect, lib/regexp など)に対して、ディレクトリ移動 (xcd)、クリーンアップ (make clean)、ビルド (time make)、テスト実行 (make test) という一連のコマンドが繰り返し記述されており、コードの重複が顕著でした。

このコミットの背景には、以下の目的があったと考えられます。

  1. コードの重複排除と保守性の向上: 繰り返し記述されているテスト実行ロジックを関数としてまとめることで、スクリプトの行数を減らし、将来的な変更やデバッグを容易にする。
  2. lib/math のテスト追加: Go言語の標準ライブラリの一部として開発が進められていた lib/math パッケージが、この時点で安定し、自動テストの対象に含める必要が生じた。これは、Go言語のコア機能が徐々に整備され、品質保証のプロセスが強化されていく過程を示唆しています。
  3. ビルド/テストプロセスの整理: 全体的なビルドおよびテストスクリプトの「クリーンアップ」を行い、より構造化された形にすることで、開発効率を高める。

前提知識の解説

このコミットの変更内容を理解するためには、以下の前提知識があると役立ちます。

1. Bashスクリプト

src/run.bash はBashシェルスクリプトで書かれています。

  • 関数定義: maketest() { ... } のように、一連のコマンドをまとめた関数を定義できます。
  • for ループ: for i; do ... done は、引数リストの各要素に対してループを実行します。この場合、maketest 関数の後に続く引数(lib/math, lib/reflect など)が i に順に代入されます。
  • サブシェル: (...) はコマンドをサブシェルで実行します。これにより、サブシェル内での cd コマンドによるディレクトリ変更が、親シェルに影響を与えません。
  • || exit $?: これは、直前のコマンドが失敗した場合(終了ステータスが0以外の場合)にスクリプト全体を終了させるための一般的なイディオムです。$? は直前のコマンドの終了ステータスを保持します。
  • \ (バックスラッシュ): 行の継続を示します。長いコマンドや引数リストを複数行に分割する際に使用されます。

2. Makefileと make コマンド

Go言語の初期のビルドシステムでは、make ユーティリティと Makefile が広く使われていました。

  • make: Makefile に記述されたルールに基づいて、プログラムのコンパイルやその他のタスクを実行するビルド自動化ツールです。
  • make clean: 通常、ビルドによって生成された中間ファイルや実行可能ファイルを削除するターゲットです。
  • make test: プロジェクトのテストを実行するターゲットです。
  • make smoketest: make test とは異なる、より基本的な、または迅速なテストセットを実行するターゲットである可能性があります。これは、完全なテストスイートを実行する前に、主要な機能が動作することを確認するための「スモークテスト」を指します。

3. Go言語の初期のディレクトリ構造

Go言語の初期のソースコードリポジトリは、現在とは異なるディレクトリ構造を持っていました。

  • src/: ソースコードのルートディレクトリ。
  • lib/: Goの標準ライブラリのパッケージが置かれていた場所。現在の src/ の直下に各パッケージがある構造とは異なります。
  • usr/: ユーザーが作成した、または実験的なコードが置かれていた場所。../usr/gri/pretty は、gri というユーザー(おそらくRob Pikeの初期のハンドルネームの一つ)が作成した pretty というプロジェクトを指していると考えられます。

4. xcd 関数

src/run.bash の冒頭で定義されている xcd 関数は、cd コマンドのラッパーです。

xcd() {
	builtin cd $1
}

これは、単に cd コマンドを実行するだけですが、将来的に cd の動作に何らかのロギングやエラーチェックを追加する可能性を考慮して、関数として定義されていたと考えられます。builtin cd は、シェルに組み込まれている cd コマンドを明示的に呼び出すことで、同名のシェル関数やエイリアスが存在する場合でも、組み込みコマンドが優先されるようにします。

技術的詳細

このコミットの技術的詳細は、主に src/run.bash スクリプトの構造化とテストカバレッジの拡張にあります。

  1. maketest 関数の導入:

    • この関数は、Goの各ライブラリのビルドとテストの標準的な手順をカプセル化します。具体的には、指定されたディレクトリに移動し (xcd $i)、クリーンアップ (make clean)、ビルド (time make)、そしてテスト実行 (make test) を行います。
    • time make は、ビルドにかかる時間を計測するために使用されています。これは、初期のGo開発においてビルドパフォーマンスが重要な関心事であったことを示唆しています。
    • || exit $? を各ステップではなく、サブシェル全体 ((...) || exit $?) に適用することで、いずれかのステップでエラーが発生した場合に、そのライブラリのテスト実行を中断し、スクリプト全体を終了させる堅牢なエラーハンドリングを実現しています。
  2. lib/math のテスト追加:

    • maketest 関数が導入されたことで、lib/math を含む複数のライブラリに対して、統一された方法でテストを実行できるようになりました。
    • lib/math は、Go言語の標準ライブラリの中でも基本的な数値計算機能を提供する重要なパッケージです。このコミットでテストスイートに追加されたことは、その安定性と品質がこの時点で重視され始めたことを意味します。
  3. コードの再編成と可読性:

    • 重複するコードブロックを maketest 関数に置き換えることで、スクリプトの行数が減少し、全体的な構造がより明確になりました。
    • これにより、新しいライブラリのテストを追加する際も、maketest の引数リストにそのライブラリのパスを追加するだけで済むようになり、保守性が大幅に向上しました。
  4. 例外処理の明示:

    • # all of these are subtly different # from what maketest does. というコメントは、../usr/gri/pretty../usr/gri/gosrc のような特定のモジュールが、maketest 関数で定義された標準的なテスト手順とは異なる独自の要件を持っていることを明確に示しています。
    • ../usr/gri/prettymake test の代わりに make smoketest を実行しており、これはそのモジュールが異なるテストフェーズやテストタイプを持っていることを示唆しています。このような例外を明示することで、スクリプトの意図が明確になり、将来的な誤解を防ぎます。

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

src/run.bash の変更箇所は以下の通りです。

--- a/src/run.bash
+++ b/src/run.bash
@@ -11,22 +11,31 @@ xcd() {
 	builtin cd $1
 }
 
-(xcd lib/strconv
-make clean
-time make
-make test
-) || exit $?\n
-
-(xcd lib/reflect
-make clean
-time make
-make test
-) || exit $?\n
-
-+maketest() {
++maketest() {
++	for i
++	do
++		(
++			xcd $i
++			make clean
++			time make
++			make test
++		) || exit $?
++	done
++}
++
++maketest \
++	lib/math\
++	lib/reflect\
++	lib/regexp\
++	lib/strconv\
++
++# all of these are subtly different
++# from what maketest does.
+
 (xcd lib/regexp
 make clean
 time make
-make test
+make smoketest
 ) || exit $?\n
 
 (xcd ../usr/gri/gosrc
@@ -35,12 +44,6 @@ time make
 # make test
 ) || exit $?\n
 
-(xcd ../usr/gri/pretty
-make clean
-time make
-make smoketest
-) || exit $?\n
-\n
 (xcd ../test
 ./run
 ) || exit $?\n

コアとなるコードの解説

このコミットの核となる変更は、maketest シェル関数の導入とその利用です。

  1. maketest 関数の定義:

    maketest() {
    	for i
    	do
    		(
    			xcd $i
    			make clean
    			time make
    			make test
    		) || exit $?
    	done
    }
    

    この関数は、引数として渡された各ディレクトリ ($i) に対して、以下の標準的なテスト手順を実行します。

    • xcd $i: 指定されたディレクトリに移動します。
    • make clean: ビルド成果物をクリーンアップします。
    • time make: プロジェクトをビルドし、その時間を計測します。
    • make test: テストを実行します。 各ステップはサブシェル (...) 内で実行され、いずれかのステップが失敗した場合は || exit $? によってスクリプト全体が終了します。
  2. maketest 関数の呼び出し:

    maketest \
    	lib/math\
    	lib/reflect\
    	lib/regexp\
    	lib/strconv\
    

    ここで maketest 関数が呼び出され、lib/math, lib/reflect, lib/regexp, lib/strconv の各パスが引数として渡されます。これにより、これらのライブラリに対して上記で定義された標準的なテスト手順が自動的に適用されます。特に lib/math がこのリストに追加されたことが、このコミットの主要な目的の一つです。

  3. 例外処理のコメント:

    # all of these are subtly different
    # from what maketest does.
    

    このコメントは、その後に続く ../usr/gri/pretty../usr/gri/gosrc のようなブロックが、maketest 関数で定義された一般的なテスト手順とは異なる特別な処理を必要とすることを示しています。例えば、../usr/gri/prettymake test の代わりに make smoketest を実行しており、これはそのモジュールに特有のテスト要件があることを示唆しています。

これらの変更により、src/run.bash スクリプトはよりモジュール化され、Go言語の初期のビルドおよびテストプロセスが効率化されました。

関連リンク

  • Go言語の公式GitHubリポジトリ: https://github.com/golang/go
  • Go言語の初期のコミット履歴を辿ることで、当時の開発状況や他の関連する変更を理解できます。

参考にした情報源リンク

  • Bashスクリプトの基本的な構文と機能に関するドキュメント(例: GNU Bash Manual)
  • make コマンドと Makefile の使用方法に関するドキュメント(例: GNU Make Manual)
  • Go言語の初期の歴史や開発に関する記事やドキュメント(例: The Go Programming Language Blog, Go Wiki)
  • GitHubのコミット履歴と差分表示機能。