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

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

misc/dist/bindist.go は、Go言語の公式バイナリディストリビューションを作成するための内部ツールである cmd/dist の一部です。このファイルは、Goツールチェインと標準ライブラリを様々なプラットフォーム向けにビルド、テスト、パッケージ化するプロセスにおいて、特にコンパイルされたコンポーネントを配布可能なバイナリアーカイブに組み立てるロジックを扱っています。

コミット

  • コミットハッシュ: 7cfcd2f87a13243004cd343d6ad7c0b4c7b266f6
  • 作者: Andrew Gerrand adg@golang.org
  • 日付: Mon Nov 18 13:30:25 2013 +1100
  • コミットメッセージ: misc/dist: fix file regexp

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

https://github.com/golang/go/commit/7cfcd2f87a13243004cd343d6ad7c0b4c7b266f6

元コミット内容

misc/dist: fix file regexp

This step makes it possible to upload the -osx10.x binaries
separately to their construction (after signing, for example).

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/28160043

変更の背景

このコミットの主な背景は、Go言語のバイナリ配布プロセスにおける柔軟性の向上です。特に、macOS (旧称 OS X) 向けのバイナリ (-osx10.x バイナリ) を、ビルド後に署名などの追加処理を経てから個別にアップロードできるようにすることが目的でした。

以前の正規表現では、バイナリファイル名のパターンが厳密すぎたため、ビルドされたバイナリが特定のファイル名形式に合致しない場合や、署名などの後処理によってファイル名が変更される可能性のある場合に、配布システムが正しく認識できない問題があったと考えられます。この修正により、ファイル名のマッチングがより柔軟になり、ビルドとアップロードのワークフローが分離できるようになりました。これは、セキュリティ要件(バイナリ署名など)を満たしつつ、配布プロセスを効率化するために重要な変更です。

前提知識の解説

正規表現 (Regular Expression)

正規表現は、文字列のパターンを記述するための強力なツールです。特定の文字の並び、繰り返し、選択などを簡潔に表現できます。Go言語では、regexp パッケージが正規表現の機能を提供しています。

  • ^: 文字列の先頭にマッチします。
  • $: 文字列の末尾にマッチします。
  • [a-z0-9-.]: aからzまでの小文字、0から9までの数字、ハイフン (-)、ピリオド (.) のいずれか一文字にマッチします。
  • +: 直前の要素が1回以上繰り返されることにマッチします。
  • *: 直前の要素が0回以上繰り返されることにマッチします。
  • (?:...): 非キャプチャグループ。グループ化は行いますが、マッチした部分をキャプチャしません。
  • |: 論理OR。左右のいずれかのパターンにマッチします。
  • \.: ピリオド (.) そのものにマッチします。正規表現においてピリオドは任意の1文字にマッチする特殊文字であるため、リテラルのピリオドにマッチさせるにはエスケープが必要です。

misc/dist/bindist.go の役割

misc/dist/bindist.go は、Goプロジェクトのソースコード内の内部コンポーネントであり、cmd/dist ツールの一部です。その主な目的は、Goプログラミング言語の公式バイナリディストリビューションの作成を容易にすることです。具体的には、Goツールチェインと標準ライブラリを様々なプラットフォーム向けにビルド、テスト、パッケージ化するタスクに関連しています。したがって、bindist.go は、これらのコンパイルされたコンポーネントを、ユーザーがGoをインストールするためにダウンロードする配布可能なバイナリアーカイブに組み立てるための特定のロジックを処理していると考えられます。

Go言語の配布プロセス

Go言語は、その設計上、コンパイルされたアプリケーションや再利用可能なコードモジュールの配布を容易にしています。

  1. 静的リンクされたバイナリ: Goアプリケーションは、単一の静的リンクされたバイナリにコンパイルされます。これは、コードに明示的に含まれる依存関係を除いて、実行可能ファイルが必要なすべてのランタイムコンポーネントを含んでいることを意味し、外部ランタイム依存関係を排除します。この特性により、Goアプリケーションは非常にポータブルで配布が容易です。
  2. アプリケーション配布:
    • CLIツールの場合、Go開発環境がセットアップされていれば、go install コマンドを使用してソースリポジトリから直接インストールできます。
    • Goがインストールされていないエンドユーザーへの広範な配布の場合、開発者は通常、様々なOSやアーキテクチャ向けにプリコンパイルされたバイナリを提供します。これらは通常、アーカイブ(例: .tar.gz, .zip)にパッケージ化され、簡単なインストールスクリプトが含まれることもあります。
    • GoReleaserのようなツールは、Goアプリケーションのリリースプロセス全体を自動化し、クロスコンパイル、パッケージング、GitHub Releasesなどのプラットフォームへの公開を処理します。
  3. モジュール配布: Goモジュールは、Goパッケージのコレクションであり、ソースコードリポジトリ(例: GitHub上のGitリポジトリ)から直接配布されます。他の多くの言語とは異なり、Goは単一の中央パッケージリポジトリに依存していません。
    • バージョン管理: Goモジュールは、セマンティックバージョニング(例: v1.0.0, v2.1.0)に従い、変更の性質(パッチ、マイナー、メジャー/破壊的変更)を消費者に伝えます。
    • 公開: モジュールの新しいバージョンを公開するには、開発者はソースコードリポジトリ内の関連するコミットに適切なバージョン番号でタグを付けます。

このコミットは、特にGo言語自体のバイナリ配布プロセスの一部である misc/dist ツールに関連しています。

技術的詳細

このコミットは、misc/dist/bindist.go ファイル内の正規表現 fileRe の定義を変更しています。この正規表現は、Goの配布バイナリファイルの名前を解析するために使用されます。

変更前:

var fileRe = regexp.MustCompile(
	`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]))?)\.`
)

この正規表現は、ファイル名の末尾に特定の拡張子を要求していませんでした。最後の \. は、ファイル名がピリオドで終わることを意味していました。これは、go1.2.src.go1.2.linux-amd64. のような形式にマッチしますが、実際の配布ファイルは通常 .tar.gz.zip などのアーカイブ拡張子を持っています。

変更後:

var fileRe = regexp.MustCompile(`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]+))?)\.(tar\.gz|zip|pkg|msi)$`)

変更後の正規表現では、ファイル名の末尾に具体的なアーカイブ拡張子を明示的に指定しています。

  • (tar\\.gz|zip|pkg|msi): これは、ファイル名が .tar.gz.zip.pkg、または .msi のいずれかで終わることを要求します。
    • tar\\.gz: tar.gz にマッチします。\. はリテラルのピリオドにマッチするためのエスケープです。
    • zip: zip にマッチします。
    • pkg: pkg にマッチします。
    • msi: msi にマッチします。
  • $: 文字列の末尾にマッチします。これにより、正規表現全体がファイル名全体にマッチすることを保証します。

この変更により、bindist.go が処理するファイルが、Goの公式配布バイナリとして期待される正確なアーカイブ形式を持つことが保証されます。特に、macOS向けの .pkg ファイルやWindows向けの .msi ファイルなど、特定のOSに特化したインストーラ形式も正しく認識できるようになりました。これにより、ビルドシステムが生成するファイル名と、配布システムが期待するファイル名の間の整合性が向上し、バイナリのアップロードと配布の信頼性が高まります。

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

--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -117,8 +117,7 @@ var staticLinkAvailable = []string{\
 	"netbsd",
 }\
 
-var fileRe = regexp.MustCompile(\
-	`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]))?)\.`)\
+var fileRe = regexp.MustCompile(`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]+))?)\.(tar\.gz|zip|pkg|msi)$`)\
 
 func main() {\
 	flag.Usage = func() {\

コアとなるコードの解説

変更されたのは、fileRe という名前の正規表現変数です。

変更前: var fileRe = regexp.MustCompile(^(go[a-z0-9-.]+).(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]))?).この正規表現は、Goのバージョン情報(例:go1.2)に続き、.srcまたはプラットフォーム情報(例:.linux-amd64)が来て、その後にピリオドで終わるファイル名にマッチしていました。しかし、実際の配布ファイルは通常、.tar.gz.zip` などのアーカイブ拡張子を持っています。この正規表現では、そのアーカイブ拡張子が考慮されていませんでした。

変更後: var fileRe = regexp.MustCompile(^(go[a-z0-9-.]+).(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]+))?).(tar.gz|zip|pkg|msi)$) この新しい正規表現は、以前のパターンに加えて、ファイル名の末尾に特定のアーカイブ拡張子を明示的に要求するようになりました。具体的には、(tar\.gz|zip|pkg|msi)$` の部分が追加されています。

  • tar\\.gz: tar.gz という文字列にマッチします。\. をリテラルとして扱うためのエスケープ文字です。
  • zip: zip という文字列にマッチします。
  • pkg: pkg という文字列にマッチします。これはmacOSのインストーラパッケージによく使われます。
  • msi: msi という文字列にマッチします。これはWindowsのインストーラパッケージによく使われます。
  • $: 文字列の終端にマッチし、ファイル名全体がこのパターンに合致することを保証します。

この修正により、bindist.go は、Goの公式バイナリ配布物として認識すべきファイル(例: go1.2.linux-amd64.tar.gz, go1.2.darwin-amd64.pkg など)を正確に識別できるようになりました。これにより、特にmacOS向けの署名済みバイナリのように、ビルド後にファイル名が特定の拡張子を持つようになるケースでも、配布システムが正しくファイルを処理できるようになります。

関連リンク

参考にした情報源リンク