[インデックス 12937] ファイルの概要
このコミットは、Go言語のディストリビューションツール (misc/dist) におけるmacOS (OS X) 向けパッケージ (.pkg) の生成方法を改善するものです。具体的には、従来の PackageMaker ユーティリティの使用を廃止し、macOSのネイティブツールである pkgbuild と productbuild を採用することで、より堅牢で柔軟なパッケージ作成プロセスを実現しています。これにより、OS X 10.6以降のバージョンを必須とするようになり、古いOSバージョンでインストールしようとした際に、よりユーザーフレンドリーなエラーメッセージを表示できるようになりました。また、postinstall スクリプトのいくつかの問題も修正されています。
コミット
commit c17d09a65774e03376fc1a7fd536646297f408cb
Author: Mikkel Krautz <mikkel@krautz.dk>
Date: Mon Apr 23 14:56:03 2012 -0700
misc/dist: require 10.6 or later for OS X .pkgs
This changes the misc/dist program to generate OS X
packages using pkgbuild and productbuild.
The productbuild utility makes it easy to generate
packages with a custom Distribution file. This allows
us to add an installcheck script that presents a
friendly message to users who are running on an old
version of Mac OS X.
The change also fixes a few issues with the
postinstall script:
- In-repo version of the script has been made
executable. Installers generated using the new
tools couldn't execute it otherwise.
- It now uses -d for checking for the existence
of the Xcode specs directory.
- The call to sudo.bash has been dropped since cov
and prof aren't bundled with the binary
distributions.
Fixes #3455.
Tested on 10.5.8, 10.6.0, 10.6.8 and 10.7.3.
R=adg, golang-dev
CC=golang-dev
https://golang.org/cl/5987044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c17d09a65774e03376fc1a7fd536646297f408cb
元コミット内容
misc/dist: require 10.6 or later for OS X .pkgs
This changes the misc/dist program to generate OS X
packages using pkgbuild and productbuild.
The productbuild utility makes it easy to generate
packages with a custom Distribution file. This allows
us to add an installcheck script that presents a
friendly message to users who are running on an old
version of Mac OS X.
The change also fixes a few issues with the
postinstall script:
- In-repo version of the script has been made
executable. Installers generated using the new
tools couldn't execute it otherwise.
- It now uses -d for checking for the existence
of the Xcode specs directory.
- The call to sudo.bash has been dropped since cov
and prof aren't bundled with the binary
distributions.
Fixes #3455.
Tested on 10.5.8, 10.6.0, 10.6.8 and 10.7.3.
R=adg, golang-dev
CC=golang-dev
https://golang.org/cl/5987044
変更の背景
この変更の主な背景には、macOS (旧称 OS X) 向けのGoバイナリディストリビューションのインストール体験の向上と、パッケージ作成プロセスの近代化があります。
-
OSバージョンの要件明確化とユーザー体験の改善: 以前のGoディストリビューションは、古いOS Xバージョンでもインストールを試みることができましたが、Goの特定の機能やビルド環境が新しいOSバージョンに依存している場合、インストール後に問題が発生する可能性がありました。このコミットでは、GoのmacOSパッケージがOS X 10.6 (Snow Leopard) 以降を必要とすることを明確にし、それ以前のバージョンでインストールしようとしたユーザーに対して、より親切で明確なエラーメッセージを表示することを目的としています。これにより、ユーザーは無駄なインストール作業を避け、互換性の問題を事前に把握できるようになります。
-
パッケージ作成ツールの移行: 従来のmacOSパッケージ作成には
PackageMakerというツールが使用されていました。しかし、PackageMakerはAppleによって非推奨とされ、より新しいpkgbuildおよびproductbuildコマンドラインツールが推奨されるようになりました。これらの新しいツールは、より柔軟なパッケージ作成オプションを提供し、特にproductbuildはカスタムのDistributionファイルを組み込むことで、インストールの事前チェックやUIのカスタマイズを容易にします。このコミットは、Goのビルドプロセスを最新のmacOS開発ツールチェーンに合わせるための重要なステップでした。 -
postinstallスクリプトの堅牢化: インストール後に実行されるpostinstallスクリプトにはいくつかの問題がありました。- 実行権限の問題: リポジトリ内のスクリプトが実行可能になっていなかったため、新しいパッケージツールで生成されたインストーラが正しく実行できない可能性がありました。
- Xcode関連パスのチェック方法の改善: Xcodeの仕様ディレクトリの存在チェックがファイル (
-f) ではなくディレクトリ (-d) として行われるべきでした。 - 不要な処理の削除: バイナリディストリビューションには
cov(カバレッジツール) やprof(プロファイリングツール) がバンドルされていないため、それらに関連するsudo.bashの呼び出しは不要であり、削除することでスクリプトの簡素化とセキュリティの向上を図りました。
これらの変更は、GoのmacOSユーザーにとって、よりスムーズで信頼性の高いインストールプロセスを提供することを目的としています。
前提知識の解説
このコミットを理解するためには、以下のmacOSパッケージングとシェルスクリプトに関する知識が役立ちます。
-
macOSインストーラパッケージ (.pkg):
- macOSアプリケーションやシステムコンポーネメントを配布・インストールするための標準的な形式です。
- 通常、インストーラアプリケーション (
Installer.app) を介して実行されます。 - 内部的には、ペイロード(インストールされるファイル群)、スクリプト(インストール前後に実行される処理)、メタデータ(パッケージ情報、インストール要件など)を含んでいます。
-
PackageMaker:- かつてmacOSでインストーラパッケージを作成するために広く使われていたGUIツールおよびコマンドラインツールです。
- Xcodeの一部として提供されていましたが、後に非推奨となりました。
- このコミット以前のGoのビルドプロセスで利用されていました。
-
pkgbuild:- macOSのコマンドラインツールで、コンポーネントパッケージ(Component Package)を作成するために使用されます。
- コンポーネントパッケージは、特定のファイルセット(ペイロード)と、それに関連するスクリプト(preinstall, postinstallなど)をまとめたものです。
pkgbuildは、インストールされる実際のファイル群と、それらをどこに配置するか、どのようなスクリプトを実行するかといった基本的な情報をカプセル化します。
-
productbuild:- macOSのコマンドラインツールで、配布パッケージ(Distribution Package)を作成するために使用されます。
- 複数のコンポーネントパッケージを一つにまとめたり、インストーラのUIや動作をカスタマイズするための
Distributionファイルを組み込んだりする際に使用されます。 productbuildは、インストーラの全体的なフロー、表示される情報、インストール条件(OSバージョンチェックなど)を制御する能力を提供します。
-
Distributionファイル:productbuildで使用されるXML形式のファイルです。- インストーラのタイトル、オプション、ドメイン、そして最も重要な
installation-checkスクリプトを定義します。 installation-checkスクリプトはJavaScriptで記述され、インストールの開始前に実行され、システムがインストール要件を満たしているかを確認します。このスクリプトがfalseを返すと、インストールは中止され、指定されたエラーメッセージが表示されます。
-
postinstallスクリプト:- macOSインストーラパッケージに含まれるシェルスクリプトの一つで、パッケージのファイルがターゲットシステムにコピーされた後に実行されます。
- インストール後のクリーンアップ、パーミッションの調整、環境変数の設定、追加の構成など、様々なタスクを実行するために使用されます。
- このコミットでは、このスクリプトの実行権限と内部ロジックが修正されています。
-
シェルスクリプトの条件式:
[ -f path ]:pathが通常のファイルとして存在するかどうかをチェックします。[ -d path ]:pathがディレクトリとして存在するかどうかをチェックします。- このコミットでは、
postinstallスクリプト内でXcode関連のディレクトリの存在チェックが-fから-dに変更されています。
これらのツールと概念を理解することで、GoのmacOSパッケージングプロセスがどのように進化し、なぜこれらの変更が行われたのかを深く把握できます。
技術的詳細
このコミットにおける技術的な変更は、主にGoのビルドスクリプト (misc/dist/bindist.go) とmacOSインストーラ関連ファイル (misc/dist/darwin/Distribution, misc/dist/darwin/scripts/postinstall) に集中しています。
-
PackageMakerからpkgbuild/productbuildへの移行:misc/dist/bindist.go内で、PackageMakerへのパスを定義していた定数packageMakerが削除されました。- パッケージ作成ロジックが大幅に変更され、
b.run関数(シェルコマンドを実行するGoのヘルパー関数)を使ってpkgbuildとproductbuildが呼び出されるようになりました。 pkgbuildの使用:- まず、
ioutil.TempDirで一時ディレクトリ (pkgdest) を作成し、そこに中間的なコンポーネントパッケージを生成します。 pkgbuildコマンドは、--identifier(パッケージの識別子)、--version、--scripts(postinstallスクリプトの場所)、--root(インストールされるファイルのルートディレクトリ)、そして出力パス (filepath.Join(pkgdest, "com.googlecode.go.pkg")) を引数に取ります。これにより、Goのバイナリと関連ファイルを含む基本的なパッケージが作成されます。
- まず、
productbuildの使用:- 次に、
productbuildコマンドが呼び出され、最終的な配布パッケージが生成されます。 --distribution引数には、新しく追加されたmisc/dist/darwin/Distributionファイルのパスが指定されます。このファイルはインストーラの動作とUIを制御します。--package-path引数には、pkgbuildで生成された中間パッケージが格納されている一時ディレクトリ (pkgdest) が指定されます。- 最後の引数
targは、最終的な.pkgファイルの出力パスです。
- 次に、
- これにより、Goのインストーラは、より現代的なmacOSのパッケージング標準に準拠し、
Distributionファイルによる高度な制御が可能になりました。
-
Distributionファイルの導入 (misc/dist/darwin/Distribution):- このコミットで新規に追加されたXMLファイルです。
installer-scriptルート要素を持ち、インストーラのメタデータと動作を定義します。- OSバージョンチェック: 最も重要な変更は、
installation-checkスクリプトの導入です。
このJavaScript関数<installation-check script="installCheck();"/> <script> function installCheck() { if(!(system.compareVersions(system.version.ProductVersion, '10.6.0') >= 0)) { my.result.title = 'Unable to install'; my.result.message = 'Go requires Mac OS X 10.6 or later.'; my.result.type = 'Fatal'; return false; } return true; } </script>installCheck()は、インストーラが起動する前に実行されます。system.compareVersionsを使用して現在のOSのバージョン (system.version.ProductVersion) が10.6.0以上であるかをチェックします。もし条件を満たさない場合、my.resultオブジェクトにエラーメッセージとタイトルを設定し、Fatalタイプとしてインストールを中止します。これにより、ユーザーはインストールを開始する前に互換性の問題を明確に知ることができます。
-
postinstallスクリプトの修正 (misc/dist/darwin/scripts/postinstall):- 実行権限の変更: ファイルのパーミッションが
100644(rw-r--r--) から100755(rwxr-xr-x) に変更されました。これにより、スクリプトがインストーラによって正しく実行可能になります。 sudo.bashの削除:
Goのバイナリディストリビューションには、デバッガに関連する-echo "Fixing debuggers via sudo.bash" -# setgrp procmod the debuggers (sudo.bash) -cd $GOROOT/src -./sudo.bashcovやprofといったツールがバンドルされていないため、それらの設定を行うsudo.bashの呼び出しは不要となり、削除されました。これはスクリプトの簡素化と、不要な特権操作の回避に貢献します。- Xcodeディレクトリチェックの修正:
Xcodeの仕様ディレクトリ (-if [ -f $XCODE_MISC_DIR ]; then +if [ -d "$XCODE_MISC_DIR" ]; then/Library/Application Support/Developer/Shared/Xcode/Specifications/) の存在チェックが、ファイル (-f) ではなくディレクトリ (-d) として行われるように修正されました。これは、パスがディレクトリを指している場合に正しいチェックを行うための重要な修正です。
- 実行権限の変更: ファイルのパーミッションが
これらの技術的な変更により、GoのmacOSパッケージはより現代的で、ユーザーフレンドリーなインストール体験を提供できるようになりました。
コアとなるコードの変更箇所
misc/dist/bindist.go
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -13,7 +13,6 @@ import (
"bytes"
"compress/gzip"
"encoding/base64"
- "errors"
"flag"
"fmt"
"io"
@@ -41,8 +40,7 @@ var (
)
const (
- packageMaker = "/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker"
- uploadURL = "https://go.googlecode.com/files"
+ uploadURL = "https://go.googlecode.com/files"
)
var preBuildCleanFiles = []string{
@@ -231,7 +229,7 @@ func (b *Build) Do() error {
return err
}
localDir := filepath.Join(work, "usr/local")
- err = os.MkdirAll(localDir, 0744)
+ err = os.MkdirAll(localDir, 0755)
if err != nil {
return err
}
@@ -240,27 +238,29 @@ func (b *Build) Do() error {
return err
}
// build package
- pkginfo, err := createPackageInfo(work)
+ pkgdest, err := ioutil.TempDir("", "pkgdest")
if err != nil {
return err
}
- defer os.Remove(pkginfo)
- pm := packageMaker
- if !exists(pm) {
- pm = "/Developer" + pm
- if !exists(pm) {
- return errors.New("couldn't find PackageMaker")
- }
+ defer os.RemoveAll(pkgdest)
+ dist := filepath.Join(runtime.GOROOT(), "misc/dist")
+ _, err = b.run("", "pkgbuild",
+ "--identifier", "com.googlecode.go",
+ "--version", "1.0",
+ "--scripts", filepath.Join(dist, "darwin/scripts"),
+ "--root", work,
+ filepath.Join(pkgdest, "com.googlecode.go.pkg"))
+ if err != nil {
+ return err
}
targ := base + ".pkg"
- scripts := filepath.Join(work, "usr/local/go/misc/dist/darwin/scripts")
- _, err = b.run("", pm, "-v",
- "-r", work,
- "-o", targ,
- "--info", pkginfo,
- "--scripts", scripts,
- "--title", "Go",
- "--target", "10.5")
+ _, err = b.run("", "productbuild",
+ "--distribution", filepath.Join(dist, "darwin/Distribution"),
+ "--package-path", pkgdest,
+ targ)
+ if err != nil {
+ return err
+ }
targs = append(targs, targ)
case "windows":
// Create ZIP file.
@@ -806,30 +806,3 @@ func tarFileInfoHeader(fi os.FileInfo, filename string) (*tar.Header, error) {
}
return h, nil
}
-
-// createPackageInfo creates a PackageInfo template file for use with PackageMaker.
-// The returned filename points to a file in a temporary directory on the filesystem,
-// and should be removed after use.
-func createPackageInfo(work string) (filename string, err error) {
- var size, nfiles int64
- err = filepath.Walk(work, func(path string, info os.FileInfo, err error) error {
- nfiles++
- size += info.Size()
- return nil
- })
- if err != nil {
- return "", err
- }
- pi, err := ioutil.TempFile("", "PackageInfo")
- if err != nil {
- return "", err
- }
- defer pi.Close()
- _, err = fmt.Fprintf(pi, "<pkg-info identifier=\"com.googlecode.go\" version=\"1.0\" followSymLinks=\"true\">\\n"+
- "\\t<payload installKBytes=\"%v\" numberOfFiles=\"%v\"/>\\n"+
- "</pkg-info>\\n", size/1024, nfiles)
- if err != nil {
- return "", err
- }
- return pi.Name(), nil
-}
misc/dist/darwin/Distribution (新規ファイル)
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<installer-script minSpecVersion="1.000000">
<title>Go</title>
<options customize="never" allow-external-scripts="no"/>
<domains enable_localSystem="true" />
<installation-check script="installCheck();"/>
<script>
function installCheck() {
if(!(system.compareVersions(system.version.ProductVersion, '10.6.0') >= 0)) {
my.result.title = 'Unable to install';
my.result.message = 'Go requires Mac OS X 10.6 or later.';
my.result.type = 'Fatal';
return false;
}
return true;
}
</script>
<choices-outline>
<line choice="com.googlecode.go.choice"/>
</choices-outline>
<choice id="com.googlecode.go.choice" title="Go">
<pkg-ref id="com.googlecode.go.pkg"/>
</choice>
<pkg-ref id="com.googlecode.go.pkg" auth="Root">com.googlecode.go.pkg</pkg-ref>
</installer-script>
misc/dist/darwin/scripts/postinstall
--- a/misc/dist/darwin/scripts/postinstall
+++ b/misc/dist/darwin/scripts/postinstall
@@ -9,14 +9,9 @@ find bin -exec chmod ugo+rx \\{\\} \\;\n find . -type d -exec chmod ugo+rx \\{\\} \\;\n chmod o-w .\n \n-echo "Fixing debuggers via sudo.bash"\n-# setgrp procmod the debuggers (sudo.bash)\n-cd $GOROOT/src\n-./sudo.bash
-\n echo "Installing miscellaneous files:"\n XCODE_MISC_DIR="/Library/Application Support/Developer/Shared/Xcode/Specifications/"\n-if [ -f $XCODE_MISC_DIR ]; then
-+if [ -d "$XCODE_MISC_DIR" ]; then
\techo " XCode"\n \tcp $GOROOT/misc/xcode/* $XCODE_MISC_DIR\n fi
コアとなるコードの解説
misc/dist/bindist.go の変更点
PackageMaker関連の削除:packageMaker定数とcreatePackageInfo関数が削除されました。これは、GoのmacOSパッケージ作成プロセスがPackageMakerから完全に移行したことを意味します。- ディレクトリパーミッションの変更:
os.MkdirAll(localDir, 0744)がos.MkdirAll(localDir, 0755)に変更されました。0744は所有者に読み書き実行、グループとその他に読み取りのみを許可しますが、0755は所有者に読み書き実行、グループとその他に読み取りと実行を許可します。これは、インストールされるディレクトリの実行権限をより適切に設定するための変更と考えられます。 pkgbuildとproductbuildの導入:ioutil.TempDir("", "pkgdest")で一時ディレクトリを作成し、pkgbuildコマンドの出力先として利用しています。b.run("", "pkgbuild", ...):pkgbuildを呼び出し、Goのインストールルート (work) をペイロードとして、misc/dist/darwin/scriptsをスクリプトディレクトリとして指定し、中間パッケージ (com.googlecode.go.pkg) を生成します。b.run("", "productbuild", ...):productbuildを呼び出し、misc/dist/darwin/Distributionファイルを配布設定として、pkgbuildで生成された中間パッケージ (pkgdest) をソースとして、最終的な.pkgファイルを生成します。このDistributionファイルが、OSバージョンチェックなどのインストーラ動作を定義します。
- エラーハンドリングの改善:
errorsパッケージのインポートが不要になったのは、createPackageInfo関数が削除されたためです。
misc/dist/darwin/Distribution の新規追加
このXMLファイルは、macOSインストーラの振る舞いを定義する中心的な役割を担います。
title: インストーラのウィンドウに表示されるタイトルを「Go」と設定します。options: インストーラのカスタマイズを許可しない (customize="never")、外部スクリプトを許可しない (allow-external-scripts="no") といったオプションを設定します。installation-check: ここが最も重要な部分で、installCheck()というJavaScript関数をインストールの事前チェックとして指定しています。scriptブロック:installCheck()関数の実装が含まれています。system.compareVersions(system.version.ProductVersion, '10.6.0') >= 0は、現在のmacOSのバージョンが10.6.0以上であるかを比較します。- もしバージョンが要件を満たさない場合、
my.result.title、my.result.message、my.result.typeを設定し、Fatalタイプのエラーとしてインストールを中止します。これにより、ユーザーは「Go requires Mac OS X 10.6 or later.」という明確なメッセージを受け取ります。
choices-outlineとchoice: インストールするパッケージの選択肢を定義します。ここでは「Go」という単一の選択肢が提供され、com.googlecode.go.pkgというパッケージを参照しています。pkg-ref: 実際にインストールされるパッケージの参照を定義します。
misc/dist/darwin/scripts/postinstall の変更点
- 実行権限の変更: ファイルモードが
100644から100755に変更されました。これは、このスクリプトがインストーラによって実行される際に、適切な実行権限を持つことを保証します。 sudo.bash関連コードの削除:echo "Fixing debuggers via sudo.bash"やcd $GOROOT/src; ./sudo.bashといった行が削除されました。- これは、Goのバイナリディストリビューションには
covやprofといったデバッガ関連ツールがバンドルされていないため、それらの設定を行うためのsudo.bashの呼び出しが不要になったためです。これにより、スクリプトが簡素化され、不要な特権操作が回避されます。
- Xcodeディレクトリチェックの修正:
if [ -f $XCODE_MISC_DIR ]; thenがif [ -d "$XCODE_MISC_DIR" ]; thenに変更されました。XCODE_MISC_DIRは/Library/Application Support/Developer/Shared/Xcode/Specifications/を指しており、これはディレクトリです。[ -f ... ]はファイルが存在するかをチェックするのに対し、[ -d ... ]はディレクトリが存在するかをチェックします。この修正により、Xcode関連のファイルのコピーが、正しい条件で実行されるようになりました。
これらの変更は、GoのmacOSパッケージのビルドとインストールプロセスを、より現代的で堅牢、かつユーザーフレンドリーなものにするための重要なステップです。
関連リンク
- GitHub上のコミットページ
- Gerrit Change-ID: 5987044
- Go Issue #3455: misc/dist: require 10.6 or later for OS X .pkgs