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

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

このコミットは、Go言語の配布ツール (misc/dist/bindist.go) に関連する変更です。具体的には、Mac OS X (darwin) 向けのバイナリ配布物生成プロセスにおいて、.tar.gz 形式のアーカイブ(tarball)の生成を追加し、それに伴うアップロード時のラベル付けロジックを改善しています。

コミット

  • コミットハッシュ: 79de0d00ae68a2fd272863a965dc08aec47d73b1
  • Author: Andrew Gerrand adg@golang.org
  • Date: Mon Sep 17 16:59:16 2012 -0700
  • 変更ファイル: misc/dist/bindist.go
  • 変更行数: 27行追加, 15行削除

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

https://github.com/golang/go/commit/79de0d00ae68a2fd272863a965dc08aec47d73b1

元コミット内容

misc/dist: generate tarballs for Mac OS X

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6503118

変更の背景

この変更の背景には、Go言語のバイナリ配布戦略の進化があります。以前はMac OS X向けには主に.pkg形式のインストーラが提供されていましたが、開発者や特定のユースケースにおいては、より汎用的な.tar.gz形式のアーカイブが求められることがありました。.tar.gz形式は、インストーラを介さずに直接ファイルを展開して利用できるため、CI/CD環境での利用や、特定のディレクトリにGoをインストールしたい場合に柔軟性を提供します。

このコミットは、Mac OS XユーザーがGoバイナリをより簡単に、かつ多様な方法で利用できるようにするための改善の一環として、.tar.gz形式の配布物生成を公式の配布プロセスに組み込むことを目的としています。また、それに伴い、生成されたファイルのタイプ(インストーラかアーカイブか)を正確に識別し、アップロード時に適切なラベルを付与するためのロジックの調整も行われています。これにより、配布物の管理とユーザーへの情報提供がより明確になります。

前提知識の解説

misc/dist パッケージ

misc/dist はGoプロジェクト内のディレクトリで、Go言語の公式バイナリ配布物を生成するためのツールやスクリプトが含まれています。これは、Goのリリースプロセスにおいて、様々なオペレーティングシステムやアーキテクチャ向けの実行可能ファイルやライブラリをパッケージ化し、配布可能な形式にまとめる役割を担っています。

bindist.go

bindist.gomisc/dist パッケージの中核をなすGoプログラムです。このプログラムは、Goのソースコードから各プラットフォーム向けのバイナリをビルドし、それを特定の形式(例: .zip, .tar.gz, .pkg, .msi など)にパッケージ化する処理を自動化します。

Tarball (.tar.gz)

Tarballは、複数のファイルを一つのアーカイブにまとめるためのtarコマンドと、そのアーカイブを圧縮するためのgzipコマンドを組み合わせたファイル形式です。拡張子は通常.tar.gzまたは.tgzとなります。Unix系システムで広く利用されており、ソフトウェアの配布によく用いられます。インストーラを必要とせず、展開するだけで内容にアクセスできるため、柔軟な配置が可能です。

PKG (.pkg)

PKGは、macOS (旧Mac OS X) で使用されるインストーラパッケージ形式です。AppleのInstallerアプリケーションによって実行され、ソフトウェアをシステムにインストールするための手順やリソースを含んでいます。通常、アプリケーションやフレームワークを/Applications/Libraryなどの標準的なシステムディレクトリに配置するために使用されます。

productbuild コマンド

productbuild はmacOSに標準で搭載されているコマンドラインツールで、macOSインストーラパッケージ(.pkgファイル)を作成するために使用されます。このツールは、配布用のインストーラを作成する際に、署名やリソースの埋め込みなど、様々なオプションを提供します。

アップロード時のラベル付け (labels)

Goの配布プロセスでは、生成されたバイナリパッケージをGoogle Code (当時) やGoのダウンロードページにアップロードする際に、そのファイルがどのような特性を持つかを示す「ラベル」を付与していました。これらのラベルは、ファイルの検索性やフィルタリングを向上させ、ユーザーが目的のファイルを簡単に見つけられるようにするために重要です。例えば、「Type-Archive」(アーカイブファイル)、「Type-Installer」(インストーラファイル)、「OpSys-OSX」(Mac OS X用)などのラベルが付与されます。

技術的詳細

このコミットの技術的な変更は、主に bindist.go ファイル内の2つのセクションに集中しています。

  1. Mac OS X (darwin) 向けのtarball生成の追加: func (b *Build) Do() error メソッド内で、case "darwin": ブロックに新しいロジックが追加されました。以前はMac OS X向けには.pkgインストーラの生成が主でしたが、この変更により、.pkgの生成に加えて、makeTar関数を使用して.tar.gz形式のtarballも生成されるようになりました。これにより、Mac OS Xユーザーはインストーラとアーカイブの両方を選択できるようになります。

    // build tarball
    targ := base + ".tar.gz"
    err = makeTar(targ, work)
    targs = append(targs, targ)
    

    このコードは、base(ファイル名の基本部分)に.tar.gzを付加してターゲットファイル名を作成し、makeTar関数を呼び出してtarballを生成し、生成されたファイル名をtargsリストに追加しています。

  2. アップロード時のラベル付けロジックの改善: func (b *Build) Upload(version string, filename string) error メソッド内で、アップロード時に付与されるラベルの生成ロジックが変更されました。以前は、OSの種類とファイル名サフィックスに基づいてラベルを直接追加していましたが、この変更では、opsysftypeという2つの中間変数を使用し、より構造化された方法でラベルを構築しています。

    • opsys 変数には、b.OS(ビルド対象OS)に基づいて「Linux」「FreeBSD」「OSX」「Windows」といったOS名が格納されます。
    • ftype 変数には、filenameのサフィックス(.msi, .pkg, .zip, .tar.gz)に基づいて「Installer」「Archive」「Source」といったファイルタイプが格納されます。

    これらの変数を使用して、最終的に labels = append(labels, "OpSys-"+opsys, "Type-"+ftype) という形でラベルが追加されます。これにより、ラベル付けのロジックがより明確になり、新しいファイルタイプ(例: .tar.gz)の追加にも柔軟に対応できるようになりました。特に、Mac OS Xの場合、以前は一律で「Type-Installer」とされていましたが、この変更により.tar.gzが生成された場合は「Type-Archive」として正しく識別されるようになります。

    また、Windows向けの処理が汎用的なswitch文に統合され、.pkg.tar.gzのサフィックスに対する処理が追加されました。

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

--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -228,6 +228,12 @@ func (b *Build) Do() error {
 		err = makeTar(targ, work)
 		targs = append(targs, targ)
 	case "darwin":
+		// build tarball
+		targ := base + ".tar.gz"
+		err = makeTar(targ, work)
+		targs = append(targs, targ)
+
+		// build pkg
 		// arrange work so it's laid out as the dest filesystem
 		etc := filepath.Join(b.root, "misc/dist/darwin/etc")
 		_, err = b.run(work, "cp", "-r", etc, ".")
@@ -259,7 +265,7 @@ func (b *Build) Do() error {
 		if err != nil {
 			return err
 		}
-		targ := base + ".pkg"
+		targ = base + ".pkg"
 		_, err = b.run("", "productbuild",
 			"--distribution", filepath.Join(dist, "darwin/Distribution"),
 			"--resources", filepath.Join(dist, "darwin/Resources"),
@@ -408,35 +414,41 @@ func (b *Build) Upload(version string, filename string) error {
 	if arch != "" {
 		labels = append(labels, "Arch-"+b.Arch)
 	}
+	var opsys, ftype string // labels
 	switch b.OS {
 	case "linux":
 		os_ = "Linux"
-		labels = append(labels, "Type-Archive", "OpSys-Linux")
+		opsys = "Linux"
 	case "freebsd":
 		os_ = "FreeBSD"
-		labels = append(labels, "Type-Archive", "OpSys-FreeBSD")
+		opsys = "FreeBSD"
 	case "darwin":
 		os_ = "Mac OS X"
-		labels = append(labels, "Type-Installer", "OpSys-OSX")
+		opsys = "OSX"
 	case "windows":
 		os_ = "Windows"
-		labels = append(labels, "OpSys-Windows")
+		opsys = "Windows"
 	}
 	summary := fmt.Sprintf("%s %s (%s)", version, os_, arch)
-	if b.OS == "windows" {
-		switch {
-		case strings.HasSuffix(filename, ".msi"):
-			labels = append(labels, "Type-Installer")
-			summary += " MSI installer"
-		case strings.HasSuffix(filename, ".zip"):
-			labels = append(labels, "Type-Archive")
-			summary += " ZIP archive"
-		}
+	switch {
+	case strings.HasSuffix(filename, ".msi"):
+		ftype = "Installer"
+		summary += " MSI installer"
+	case strings.HasSuffix(filename, ".pkg"):
+		ftype = "Installer"
+		summary += " PKG installer"
+	case strings.HasSuffix(filename, ".zip"):
+		ftype = "Archive"
+		summary += " ZIP archive"
+	case strings.HasSuffix(filename, ".tar.gz"):
+		ftype = "Archive"
+		summary += " tarball"
 	}
 	if b.Source {
-		labels = append(labels, "Type-Source")
+		ftype = "Source"
 		summary = fmt.Sprintf("%s (source only)", version)
 	}
+	labels = append(labels, "OpSys-"+opsys, "Type-"+ftype)
 	if *addLabel != "" {
 		labels = append(labels, *addLabel)
 	}

コアとなるコードの解説

func (b *Build) Do() error 内の変更

  • 追加された部分:
    case "darwin":
        // build tarball
        targ := base + ".tar.gz"
        err = makeTar(targ, work)
        targs = append(targs, targ)
    
        // build pkg
    
    この変更により、darwin (Mac OS X) プラットフォーム向けのビルド処理において、既存の.pkgインストーラ生成の前に、.tar.gz形式のアーカイブ(tarball)を生成するステップが追加されました。
    • targ := base + ".tar.gz": 生成されるtarballのファイル名を定義しています。baseはビルドされるGoのバージョンやアーキテクチャを含む基本名です。
    • err = makeTar(targ, work): makeTar関数を呼び出して、指定されたターゲット名 (targ) と作業ディレクトリ (work) を使用してtarballを作成します。
    • targs = append(targs, targ): 生成されたtarballのファイル名を、後でアップロード処理などで使用するためにtargs(ターゲットファイル名のリスト)に追加します。
  • 変更された部分:
    -		targ := base + ".pkg"
    +		targ = base + ".pkg"
    
    targ変数の宣言が、pkg生成ブロックの外に移動し、tar.gz生成ブロックで既に宣言されているtarg変数を再利用するように変更されました。これにより、変数のスコープが適切に管理され、コードの重複が避けられています。

func (b *Build) Upload(version string, filename string) error 内の変更

  • 追加された部分:

    	var opsys, ftype string // labels
    

    アップロード時に付与するラベルを生成するための中間変数 opsys (Operating System) と ftype (File Type) が宣言されました。これにより、ラベル生成ロジックがより整理されます。

  • 変更された部分 (OSごとのラベル付け):

    	switch b.OS {
    	case "linux":
    		os_ = "Linux"
    -		labels = append(labels, "Type-Archive", "OpSys-Linux")
    +		opsys = "Linux"
    	case "freebsd":
    		os_ = "FreeBSD"
    -		labels = append(labels, "Type-Archive", "OpSys-FreeBSD")
    +		opsys = "FreeBSD"
    	case "darwin":
    		os_ = "Mac OS X"
    -		labels = append(labels, "Type-Installer", "OpSys-OSX")
    +		opsys = "OSX"
    	case "windows":
    		os_ = "Windows"
    -		labels = append(labels, "OpSys-Windows")
    +		opsys = "Windows"
    	}
    

    以前はOSごとに直接labelsスライスにType-OpSys-のラベルを追加していましたが、この変更では、まずopsys変数にOS名を格納するようにしました。これにより、OpSys-ラベルの追加が後で一元的に行えるようになります。特にdarwinの場合、以前はType-Installerが固定で付与されていましたが、この変更により、ファイルタイプに応じた動的なラベル付けが可能になります。

  • 変更された部分 (ファイルタイプごとのラベル付け):

    -	if b.OS == "windows" {
    -		switch {
    -		case strings.HasSuffix(filename, ".msi"):
    -			labels = append(labels, "Type-Installer")
    -			summary += " MSI installer"
    -		case strings.HasSuffix(filename, ".zip"):
    -			labels = append(labels, "Type-Archive")
    -			summary += " ZIP archive"
    -		}
    -	}
    +	switch {
    +	case strings.HasSuffix(filename, ".msi"):
    +		ftype = "Installer"
    +		summary += " MSI installer"
    +	case strings.HasSuffix(filename, ".pkg"):
    +		ftype = "Installer"
    +		summary += " PKG installer"
    +	case strings.HasSuffix(filename, ".zip"):
    +		ftype = "Archive"
    +		summary += " ZIP archive"
    +	case strings.Hasuffix(filename, ".tar.gz"):
    +		ftype = "Archive"
    +		summary += " tarball"
    +	}
    

    ファイルタイプに応じたラベル付けロジックが、Windowsに限定されず、すべてのOSに適用される汎用的なswitch文に変更されました。

    • .pkg.tar.gzのサフィックスに対するケースが追加され、それぞれftype変数に「Installer」または「Archive」が設定されます。
    • これにより、Mac OS Xで生成された.tar.gzファイルも正しく「Type-Archive」として識別されるようになります。
  • 変更された部分 (最終的なラベルの追加):

    	if b.Source {
    -		labels = append(labels, "Type-Source")
    +		ftype = "Source"
     		summary = fmt.Sprintf("%s (source only)", version)
     	}
    +	labels = append(labels, "OpSys-"+opsys, "Type-"+ftype)
     	if *addLabel != "" {
     		labels = append(labels, *addLabel)
     	}
    

    b.Sourcetrueの場合(ソースコードのみの配布の場合)も、ftype変数に「Source」を設定するように変更されました。 そして、最終的にlabelsスライスにOpSys-Type-のラベルが追加されます。この変更により、OSとファイルタイプに基づくラベル付けがより柔軟かつ正確に行われるようになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (Goの配布に関する一般的な情報)
  • macOSのproductbuildコマンドに関するドキュメント (Apple Developer Documentation)
  • Tarballに関する一般的な情報 (Wikipediaなど)
  • Go言語のGitHubリポジトリ (misc/dist ディレクトリのコード構造)
  • Google Code (当時のGoのダウンロードページに関する情報)