[インデックス 16766] ファイルの概要
このコミットは、Go言語のディストリビューションにおけるmacOS (Darwin) 向けのpostinstall
スクリプトの修正に関するものです。具体的には、misc/dist/darwin/scripts/postinstall
ファイルが変更されており、Goのインストール後にXcode関連のファイルを正しく配置するための処理が改善されています。
コミット
このコミットは、macOS環境におけるGoのpostinstall
スクリプトが、Xcode関連ファイルのコピーに失敗する問題を修正します。主な原因は、パスにスペースが含まれる場合のcp
コマンドの引用符の欠如と、Xcodeのバージョンに応じた適切なソースディレクトリの選択ができていなかった点です。この修正により、Xcode 3またはXcode 4のどちらがインストールされているかに応じて、適切なGoのXcodeサポートファイルが正しくコピーされるようになります。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bbb51ae3a9dc8da80d9f48c122d8a75aead69c09
元コミット内容
commit bbb51ae3a9dc8da80d9f48c122d8a75aead69c09
Author: Alexandre Normand <alexandre.normand@gmail.com>
Date: Mon Jul 15 10:52:38 2013 +1000
dist: fix postinstall script for Darwin
The postinstall script causes the installation to fail because the last
step that copies files for Xcode is broken. Two details can cause the
command to fail:
1. The XCODE_MISC_DIR value has a space. Without quotes in the cp
command, cp will just complain that this is an invalid syntax.
2. The source of the cp is a directory with two subdirectories.
We actually want the files for either Xcode 3 or Xcode 4 to be copied.
Using xcodebuild -version, we check for the Xcode version and
select which of xcode/3/* or xcode/4/* should be the source
of the copy.
Fixes #5874.
R=golang-dev, minux.ma, adg
CC=golang-dev
https://golang.org/cl/10893044
変更の背景
この変更は、Goのインストールプロセスにおける既知のバグ、Issue 5874 (Fixes #5874
) を解決するために行われました。報告された問題は、macOS環境でGoをインストールする際に実行されるpostinstall
スクリプトが、Xcode関連のファイルをコピーする最終ステップで失敗するというものでした。
失敗の具体的な原因は以下の2点でした。
- パス内のスペースの問題: Xcodeのサポートファイルをコピーする先のディレクトリパス (
/Library/Application Support/Developer/Shared/Xcode/Specifications/
) にはスペースが含まれています。シェルスクリプトにおいて、スペースを含むパスを引用符で囲まないと、シェルはそれを複数の引数として解釈してしまい、cp
コマンドが不正な構文エラーを発生させます。 - Xcodeバージョンの特定とソース選択の不備: 以前のスクリプトでは、
$GOROOT/misc/xcode/*
という形で、xcode
ディレクトリ直下の全てのファイルをコピーしようとしていました。しかし、xcode
ディレクトリには3
と4
というサブディレクトリがあり、それぞれXcode 3とXcode 4に対応するファイルが含まれていました。スクリプトは、インストールされているXcodeのバージョンに応じて、xcode/3/*
またはxcode/4/*
のどちらか一方のファイルをコピーする必要がありました。この選択が行われていなかったため、適切なファイルがコピーされず、インストールが不完全になる可能性がありました。
これらの問題により、Goのインストールが正常に完了せず、ユーザーエクスペリエンスが損なわれていました。このコミットは、これらの問題を修正し、macOSユーザーがGoをスムーズにインストールできるようにすることを目的としています。
前提知識の解説
このコミットを理解するためには、以下の前提知識が必要です。
postinstall
スクリプト: ソフトウェアのインストールプロセスにおいて、主要なファイルの配置が完了した後に実行されるスクリプトです。追加の設定、ファイルの移動、キャッシュのクリアなど、インストール後の最終処理を行います。Goのディストリビューションでは、Xcodeとの連携に必要なファイルを配置するために使用されていました。- Xcode: Appleが提供するmacOSおよびiOSアプリケーション開発のための統合開発環境 (IDE) です。Go言語で開発されたツールがXcodeと連携する場合、特定のディレクトリにファイルを配置する必要があります。
xcodebuild
コマンド: Xcodeに付属するコマンドラインツールで、プロジェクトのビルド、テスト、アーカイブなど、Xcode関連の様々な操作を行うことができます。特に、xcodebuild -version
はインストールされているXcodeのバージョン情報を取得するために使用されます。cp
コマンド: Unix系OSでファイルやディレクトリをコピーするためのコマンドです。cp source destination
:source
をdestination
にコピーします。cp -r source_dir destination_dir
:source_dir
とその内容を再帰的にdestination_dir
にコピーします。- ワイルドカード (
*
): シェルにおいて、ファイル名の一部を任意の文字列にマッチさせるために使用されます。例えば、*.txt
は拡張子が.txt
の全てのファイルにマッチします。
- シェルスクリプトの引用符: シェルスクリプトでは、スペースや特殊文字を含む文字列を一つの引数として扱うために、ダブルクォーテーション (
"
) またはシングルクォーテーション ('
) で囲む必要があります。ダブルクォーテーション内では変数展開 ($VAR
) が行われますが、シングルクォーテーション内では行われません。 if [ -d "path" ]
: シェルスクリプトの条件分岐で、指定されたpath
がディレクトリとして存在するかどうかをチェックします。mkdir -p
: ディレクトリを作成するコマンドです。-p
オプションを付けると、親ディレクトリが存在しない場合でも、それらも同時に作成します。既にディレクトリが存在してもエラーになりません。sed
コマンド: ストリームエディタ (Stream EDitor) で、テキストの変換や置換を行うために使用されます。sed -n -E 's/pattern/replacement/p'
:-n
は通常出力を抑制し、p
フラグが付いた行のみを出力します。-E
は拡張正規表現を使用可能にします。s/pattern/replacement/
はpattern
にマッチした部分をreplacement
に置換します。
grep
コマンド: テキストファイルから特定のパターンにマッチする行を検索して表示するコマンドです。$?
(終了ステータス): シェルスクリプトにおいて、直前に実行されたコマンドの終了ステータスを保持する特殊変数です。通常、0
は成功を意味し、0以外
は失敗を意味します。[[ ... ]]
: Bashなどのシェルで使われる条件式です。[ ... ]
よりも高機能で、正規表現マッチング (=~
) やより複雑な条件式をサポートします。
技術的詳細
このコミットの技術的詳細は、macOSのファイルシステム構造、Xcodeのバージョン管理、および堅牢なシェルスクリプトの記述に焦点を当てています。
-
Xcode関連ファイルの配置パス: GoのXcodeサポートファイルは、XcodeがGo言語を認識し、Goプロジェクトを適切に扱えるようにするために、特定のディレクトリに配置される必要があります。このパスは
/Library/Application Support/Developer/Shared/Xcode/Specifications/
であり、このパスにはスペースが含まれています。以前のスクリプトでは、このパスをcp
コマンドの引数として渡す際に引用符で囲んでいなかったため、シェルがパスを複数の単語として解釈し、cp
コマンドがエラーを発生させていました。 -
Xcodeバージョンの動的な検出: GoのXcodeサポートファイルは、Xcode 3とXcode 4で異なる構造を持っていました。以前のスクリプトは、単純に
$GOROOT/misc/xcode/*
をコピーしようとしていましたが、これはxcode/3
とxcode/4
の両方の内容をコピーしようとするか、あるいは意図しない動作を引き起こす可能性がありました。 この修正では、/usr/bin/xcodebuild -version
コマンドを使用して、現在インストールされているXcodeのバージョンを動的に検出します。xcodebuild -version
の出力例:Xcode 4.6.3
sed -n -E 's/^Xcode ([0-9]+)\..*$/\1/p'
は、この出力からメジャーバージョン番号(例:4
)を抽出します。^Xcode
: 行頭の"Xcode "にマッチ。([0-9]+)
: 1つ以上の数字にマッチし、それをキャプチャグループ1として記憶。これがXcodeのメジャーバージョン番号になります。\.
: ドット文字にマッチ(エスケープが必要)。.*$
: 残りの任意の文字にマッチし、行末まで。\1
: キャプチャグループ1の内容(メジャーバージョン番号)に置換。p
: マッチした行をプリント。
- この抽出されたバージョン番号 (
version
変数) を使用して、$GOROOT/misc/xcode/$version/*
というパスを構築し、適切なバージョンのファイルのみをコピーするようにします。
-
xcodebuild -version
の失敗時のフォールバック: コミットメッセージにもあるように、Xcode 4ではコマンドラインツールがオプションであったため、xcodebuild -version
コマンドが失敗する可能性がありました。スクリプトは、このコマンドの終了ステータス ($?
) をチェックし、失敗 ($? -ne 0
) した場合には、デフォルトでXcode 4が使用されていると解釈し、version=4
を設定するフォールバックロジックが追加されました。これにより、コマンドラインツールがインストールされていない環境でも、スクリプトが適切に動作するようになります。 -
ディレクトリの存在確認と作成:
XCODE_SHARED_DIR
(/Library/Application Support/Developer/Shared/Xcode
) が存在するかどうかを確認し、存在しない場合はmkdir -p "$XCODE_MISC_DIR"
で必要なディレクトリ構造を再帰的に作成するように変更されました。これにより、ターゲットディレクトリが存在しない場合でもスクリプトが失敗することなく、必要なディレクトリが自動的に作成されます。
これらの変更により、スクリプトはより堅牢になり、様々なmacOS環境およびXcodeのバージョンに対応できるようになりました。
コアとなるコードの変更箇所
--- a/misc/dist/darwin/scripts/postinstall
+++ b/misc/dist/darwin/scripts/postinstall
@@ -10,9 +10,22 @@ find . -type d -exec chmod ugo+rx \\{\\} \\;\n chmod o-w .\n \n echo "Installing miscellaneous files:"\n-XCODE_MISC_DIR="/Library/Application Support/Developer/Shared/Xcode/Specifications/"\n-if [ -d "$XCODE_MISC_DIR" ]; then\n-\techo " XCode"\n-\tcp $GOROOT/misc/xcode/* $XCODE_MISC_DIR
+XCODE_SHARED_DIR="/Library/Application Support/Developer/Shared/Xcode"\n+XCODE_MISC_DIR="$XCODE_SHARED_DIR/Specifications/"\n+if [ -d "$XCODE_SHARED_DIR" ]; then
+\t# Create the XCODE_MISC_DIR if it doesn\'t exist already
+\tmkdir -p "$XCODE_MISC_DIR"\n+\n+\tversion=`/usr/bin/xcodebuild -version | sed -n -E \'s/^Xcode ([0-9]+)\\..*$/\\1/p\'`\n+ \n+ # Since command line tools are optional with Xcode 4, a failure of the \n+\t# xcodebuild -version command is interpreted as meaning Xcode 4 is the \n+\t# version used.\n+\tif [[ $? -ne 0 ]]; then\n+\t\tversion=4\n+\tfi\n+\n+ echo " Xcode $version"\n+\tcp $GOROOT/misc/xcode/$version/* "$XCODE_MISC_DIR"\n fi
コアとなるコードの解説
変更されたコードブロックは、Goのインストール後にXcode関連のファイルを正しく配置するためのロジックを含んでいます。
-
XCODE_SHARED_DIR
とXCODE_MISC_DIR
の定義:XCODE_SHARED_DIR="/Library/Application Support/Developer/Shared/Xcode" XCODE_MISC_DIR="$XCODE_SHARED_DIR/Specifications/"
XCODE_SHARED_DIR
はXcodeの共有サポートファイルのルートディレクトリを定義します。XCODE_MISC_DIR
は、その中に含まれるSpecifications
ディレクトリを指し、GoのXcodeサポートファイルが最終的にコピーされる場所です。以前のバージョンではXCODE_MISC_DIR
が直接定義されていましたが、XCODE_SHARED_DIR
を導入することで、パスの構造がより明確になり、後のmkdir -p
での使用が容易になります。 -
XCODE_SHARED_DIR
の存在チェック:if [ -d "$XCODE_SHARED_DIR" ]; then
XCODE_SHARED_DIR
が存在するかどうかを確認します。このディレクトリが存在しない場合、Xcodeがインストールされていないか、異なるパスにインストールされている可能性があり、Xcode関連ファイルのコピーは意味がありません。 -
XCODE_MISC_DIR
の作成:# Create the XCODE_MISC_DIR if it doesn\'t exist already mkdir -p "$XCODE_MISC_DIR"
XCODE_MISC_DIR
が存在しない場合に、mkdir -p
コマンドを使用してそのディレクトリを作成します。-p
オプションにより、必要な親ディレクトリも同時に作成されるため、スクリプトの堅牢性が向上します。また、パスがダブルクォーテーションで囲まれているため、パスにスペースが含まれていても正しく処理されます。 -
Xcodeバージョンの検出:
version=`/usr/bin/xcodebuild -version | sed -n -E \'s/^Xcode ([0-9]+)\\..*$/\\1/p\'`
/usr/bin/xcodebuild -version
を実行し、その出力からXcodeのメジャーバージョン番号を抽出します。sed
コマンドが正規表現を使用してバージョン番号をパースし、結果をversion
変数に格納します。 -
xcodebuild
コマンド失敗時のフォールバック:# Since command line tools are optional with Xcode 4, a failure of the # xcodebuild -version command is interpreted as meaning Xcode 4 is the # version used. if [[ $? -ne 0 ]]; then version=4 fi
直前の
xcodebuild
コマンドの終了ステータス ($?
) をチェックします。もし0
以外(失敗)であれば、Xcode 4のコマンドラインツールがインストールされていない可能性を考慮し、version
変数を4
に設定します。これにより、コマンドラインツールが不足している環境でも、スクリプトがXcode 4用のファイルをコピーしようとします。 -
Xcodeバージョンに応じたファイルのコピー:
echo " Xcode $version" cp $GOROOT/misc/xcode/$version/* "$XCODE_MISC_DIR"
検出された(またはフォールバックされた)Xcodeバージョン (
$version
) を使用して、$GOROOT/misc/xcode/$version/
ディレクトリから、XcodeのサポートファイルをXCODE_MISC_DIR
にコピーします。ここでも、XCODE_MISC_DIR
がダブルクォーテーションで囲まれているため、スペースを含むパスが正しく扱われます。以前のcp $GOROOT/misc/xcode/* $XCODE_MISC_DIR
という行と比較すると、$version
が追加されたことで、Xcodeのバージョンに応じた適切なサブディレクトリからファイルがコピーされるようになり、問題が解決されています。
これらの変更により、postinstall
スクリプトはより堅牢で、Xcodeのバージョンやコマンドラインツールの有無といった様々なmacOS環境のバリエーションに対応できるようになりました。
関連リンク
- Go Issue 5874: https://code.google.com/p/go/issues/detail?id=5874 (現在はGitHubにリダイレクトされる可能性があります)
- Gerrit Change 10893044: https://golang.org/cl/10893044