[インデックス 19731] ファイルの概要
このコミットは、Go言語のgo get
コマンドがIBM DevOps Services (旧称 JazzHub) 上のGitリポジトリを正しく認識し、取得できるようにするための変更を含んでいます。具体的には、以下のファイルが変更または新規作成されました。
src/cmd/go/doc.go
:go get
コマンドの公式ドキュメントに、IBM DevOps Servicesのインポートパスの例が追加されました。これにより、ユーザーはgo get
がこのサービスをサポートしていることを認識できます。src/cmd/go/help.go
:go get
コマンドのヘルプメッセージに、IBM DevOps Servicesのインポートパスの例が追加されました。これはdoc.go
と同様に、コマンドラインからヘルプを参照するユーザーへの情報提供を目的としています。src/cmd/go/vcs.go
:go get
が様々なバージョン管理システム(VCS)のリポジトリを解決するためのロジックが含まれるファイルです。このコミットでは、hub.jazz.net
をプレフィックスとするGitリポジトリを認識するための新しいエントリがvcsPaths
変数に追加されました。src/cmd/go/vcs_test.go
:vcs.go
で定義されたリポジトリ解決ロジックが正しく機能するかを検証するためのテストファイルです。このコミットで新規作成され、特にIBM DevOps Servicesのインポートパスに対するテストケースが多数追加されました。
コミット
このコミットは、go get
コマンドがIBM DevOps Services (hub.jazz.net) のGitリポジトリをサポートするように拡張するものです。これにより、開発者はgo get
を使用して、IBM DevOps ServicesでホストされているGoパッケージを簡単に取得できるようになります。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/fd7b82b4e489c9dd34686bbc627942fd9d19c8c4
元コミット内容
go get: Support for IBM DevOps Services (hub.jazz.net) git repos
LGTM=adg
R=golang-codereviews, adg, minux
CC=golang-codereviews
https://golang.org/cl/106740044
変更の背景
go get
コマンドは、Go言語のパッケージ管理において中心的な役割を担っています。これは、指定されたインポートパスに基づいて、対応するソースコードリポジトリからパッケージをフェッチし、ビルドする機能を提供します。初期のgo get
は、GitHub、Bitbucket、Google Codeなどの主要なコードホスティングサービスをサポートしていましたが、新しいサービスや特定の企業向けプラットフォームが登場するにつれて、それらへの対応も求められるようになりました。
IBM DevOps Services(後にIBM Bluemix DevOps Services、さらにIBM Cloud Garageへと名称変更)は、IBMが提供するクラウドベースの開発プラットフォームであり、Gitリポジトリのホスティング機能も提供していました。このプラットフォームを利用しているGo開発者が、go get
を使って自身のプロジェクトや依存関係を管理できるようにするためには、go get
がhub.jazz.net
というドメインを認識し、それがGitリポジトリであることを正しく判断できる必要がありました。
このコミットは、このような背景から、go get
のVCS(バージョン管理システム)解決ロジックにIBM DevOps Servicesのパターンを追加し、より多くの開発環境に対応できるようにするために行われました。
前提知識の解説
go get
コマンド
go get
はGo言語のツールチェインの一部であり、リモートリポジトリからGoパッケージとその依存関係をダウンロードし、ローカルのGOPATH
(またはGo Modulesが有効な場合はモジュールキャッシュ)に配置するコマンドです。これにより、開発者は外部のライブラリやフレームワークを簡単にプロジェクトに組み込むことができます。go get
は、インポートパスの形式から使用されているVCS(Git, Mercurial, Subversionなど)を自動的に判別し、適切なコマンド(例: git clone
)を実行します。
Goのインポートパス
Go言語では、パッケージはインポートパスによって識別されます。このインポートパスは、通常、パッケージのソースコードがホストされているリポジトリのURL構造を反映しています。例えば、"github.com/user/repo/package"
のような形式です。go get
は、このインポートパスを解析し、どのVCSを使用しているか、そしてリポジトリのルートURLがどこにあるかを特定します。
バージョン管理システム (VCS)
VCSは、ソフトウェア開発におけるソースコードの変更履歴を管理するためのシステムです。このコミットでは主にGitが関係しています。go get
は、Git、Mercurial (Hg)、Subversion (SVN)、Bazaar (Bzr) など、複数のVCSをサポートしています。
正規表現 (Regular Expressions)
正規表現は、文字列のパターンを記述するための強力なツールです。go get
の内部では、インポートパスが特定のリポジトリパターンに一致するかどうかを判断するために正規表現が広く使用されています。これにより、柔軟かつ効率的に様々なホスティングサービスのURL構造を解析できます。
vcsPath
構造体とvcs.go
の役割
src/cmd/go/vcs.go
ファイルには、go get
がインポートパスをVCSリポジトリにマッピングするためのロジックが定義されています。このファイルの中核をなすのがvcsPath
構造体のスライスvcsPaths
です。各vcsPath
エントリは、特定のインポートパスのパターン(prefix
やre
で定義)と、それに対応するVCSの種類(vcs
)、リポジトリのURLパターン(repo
)、および追加のチェック関数(check
)を定義します。go get
は、与えられたインポートパスをvcsPaths
の各エントリと照合し、最初に見つかった一致に基づいてリポジトリ情報を特定します。
IBM DevOps Services (JazzHub)
IBM DevOps Servicesは、IBMが提供していたクラウドベースの統合開発環境(IDE)およびDevOpsツールセットです。これには、Gitリポジトリのホスティング、課題追跡、デプロイメントパイプラインなどの機能が含まれていました。Go開発者にとって、このサービスでホストされているGoパッケージをgo get
で取得できることは、開発ワークフローの統合において重要でした。hub.jazz.net
は、このサービスのGitリポジトリのURLのベースドメインでした。
技術的詳細
go get
がインポートパスを解決するプロセスは、主にsrc/cmd/go/vcs.go
内のrepoRootForImportPath
関数によって行われます。この関数は、与えられたインポートパスに対して、事前に定義されたvcsPaths
スライスを順番に走査します。各vcsPath
エントリは、特定のホスティングサービスやVCSのパターンを表現しています。
このコミットでは、vcsPaths
スライスに以下の新しいエントリが追加されました。
// IBM DevOps Services (JazzHub)
{
prefix: "hub.jazz.net/git",
re: `^(?P<root>hub.jazz.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`,
vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
このエントリの各フィールドは以下の意味を持ちます。
prefix: "hub.jazz.net/git"
: これは、インポートパスがこの文字列で始まる場合に、このvcsPath
エントリが考慮されるべきであることを示します。これにより、不要な正規表現の評価を避けることができます。re:
^(?Phub.jazz.net/git/[a-z0-9]+/[A-Za-z0-9_.-]+)(/[A-Za-z0-9_.-]+)*$ (?P<root>...)
: これは、マッチした部分をroot
という名前でキャプチャするグループです。このroot
がリポジトリのベースURLを形成します。hub.jazz.net/git/
: IBM DevOps ServicesのGitリポジトリの固定プレフィックス。[a-z0-9]+
: ユーザー名に相当する部分で、小文字の英数字が1文字以上続くことを意味します。/[A-Za-z0-9_.\-]+
: プロジェクト名(またはパッケージ名)に相当する部分で、英数字、アンダースコア、ドット、ハイフンが1文字以上続くことを意味します。(/...)
: その後の(/...)
は、サブディレクトリパス(例:/sub/directory
)が続く可能性があることを示します。
vcs: "git"
: このパターンに一致するインポートパスは、Gitバージョン管理システムを使用していることを示します。repo: "https://{root}"
: これは、実際にクローンするリポジトリのURLを構築するためのテンプレートです。正規表現でキャプチャされたroot
グループの値がここに挿入され、完全なHTTPS URLが形成されます。check: noVCSSuffix
: この関数は、インポートパスの末尾に.git
や.hg
のようなVCSサフィックスがないことを確認します。IBM DevOps Servicesのインポートパスは通常このようなサフィックスを持たないため、このチェックが適切です。
この変更により、例えばgo get hub.jazz.net/git/user1/pkgname
というコマンドが実行された場合、go get
はhttps://hub.jazz.net/git/user1/pkgname
というGitリポジトリURLを正しく特定し、そこからソースコードをダウンロードできるようになります。
また、このコミットでは、src/cmd/go/doc.go
とsrc/cmd/go/help.go
にIBM DevOps Servicesのインポートパスの例が追加され、ユーザーがこの新しいサポートについて知ることができるようになりました。
さらに重要なのは、src/cmd/go/vcs_test.go
が新規作成され、TestRepoRootForImportPath
関数にIBM DevOps Services関連の多数のテストケースが追加されたことです。これらのテストケースは、正しいインポートパスが正しく解決されること(例: hub.jazz.net/git/user1/pkgname
)、および不正なインポートパス(例: スペースを含む、不正なドメインなど)が正しくエラーとして扱われることを検証します。これにより、新しいロジックの正確性と堅牢性が保証されます。
コアとなるコードの変更箇所
src/cmd/go/vcs.go
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -613,6 +613,15 @@ var vcsPaths = []*vcsPath{
// IBM DevOps Services (JazzHub)
{
prefix: "hub.jazz.net/git",
re: `^(?P<root>hub.jazz.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`,
vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
// General syntax for any server.
{
re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
src/cmd/go/vcs_test.go
(新規作成)
--- /dev/null
+++ b/src/cmd/go/vcs_test.go
@@ -0,0 +1,116 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "testing"
+)
+
+// Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
+// TODO(cmang): Add tests for SVN and BZR.
+func TestRepoRootForImportPath(t *testing.T) {
+ tests := []struct {
+ path string
+ want *repoRoot
+ }{
+ // ... 既存のテストケース ...
+ // IBM DevOps Services tests
+ {
+ "hub.jazz.net/git/user1/pkgname",
+ &repoRoot{
+ vcs: vcsGit,
+ repo: "https://hub.jazz.net/git/user1/pkgname",
+ },
+ },
+ {
+ "hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule",
+ &repoRoot{
+ vcs: vcsGit,
+ repo: "https://hub.jazz.net/git/user1/pkgname",
+ },
+ },
+ {
+ "hub.jazz.net",
+ nil,
+ },
+ {
+ "hub2.jazz.net",
+ nil,
+ },
+ {
+ "hub.jazz.net/someotherprefix",
+ nil,
+ },
+ {
+ "hub.jazz.net/someotherprefix/user1/pkgname",
+ nil,
+ },
+ // Spaces are not valid in user names or package names
+ {
+ "hub.jazz.net/git/User 1/pkgname",
+ nil,
+ },
+ {
+ "hub.jazz.net/git/user1/pkg name",
+ nil,
+ },
+ // Dots are not valid in user names
+ {
+ "hub.jazz.net/git/user.1/pkgname",
+ nil,
+ },
+ {
+ "hub.jazz.net/git/user/pkg.name",
+ &repoRoot{
+ vcs: vcsGit,
+ repo: "https://hub.jazz.net/git/user/pkg.name",
+ },
+ },
+ // User names cannot have uppercase letters
+ {
+ "hub.jazz.net/git/USER/pkgname",
+ nil,
+ },
+ }
+
+ for _, test := range tests {
+ got, err := repoRootForImportPath(test.path)
+ want := test.want
+
+ if want == nil {
+ if err == nil {
+ t.Errorf("RepoRootForImport(%q): Error expected but not received")
+ }
+ continue
+ }
+ if err != nil {
+ t.Errorf("RepoRootForImport(%q): %v", test.path, err)
+ continue
+ }
+ if got.vcs.name != want.vcs.name || got.repo != want.repo {
+ t.Errorf("RepoRootForImport(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.vcs, got.repo, want.vcs, want.repo)
+ }
+ }
+}
コアとなるコードの解説
src/cmd/go/vcs.go
の変更
追加されたvcsPath
エントリは、go get
がhub.jazz.net/git/
で始まるインポートパスをどのように処理すべきかを明確に定義しています。
prefix: "hub.jazz.net/git"
: このプレフィックスにより、go get
はインポートパスがこの文字列で始まる場合にのみ、この特定のルールを適用しようとします。これはパフォーマンスの最適化にも寄与します。re:
^(?Phub.jazz.net/git/[a-z0-9]+/[A-Za-z0-9_.-]+)(/[A-Za-z0-9_.-]+)*$ [a-z0-9]+
: ユーザー名部分が小文字の英数字のみであることを強制します。これは、テストケースで大文字のユーザー名がnil
(エラー)となる理由を説明しています。[A-Za-z0-9_.\-]+
: パッケージ名部分が英数字、アンダースコア、ドット、ハイフンを許容することを示します。(?P<root>...)
: この名前付きキャプチャグループは、リポジトリのルートURLを抽出するために使用されます。例えば、hub.jazz.net/git/user1/pkgname
というパスの場合、root
はhub.jazz.net/git/user1/pkgname
となります。
vcs: "git"
: このパターンにマッチするパスはGitリポジトリとして扱われます。repo: "https://{root}"
: 抽出されたroot
の値を使用して、最終的なリポジトリURLがhttps://hub.jazz.net/git/user1/pkgname
のように構築されます。go get
はこのURLを使ってgit clone
を実行します。check: noVCSSuffix
: このチェックは、インポートパスの末尾に.git
などのVCSサフィックスがないことを確認します。IBM DevOps Servicesのインポートパスは通常、このようなサフィックスを含まないため、このチェックは正しい動作を保証します。
src/cmd/go/vcs_test.go
の新規作成とテストケース
このファイルは、go get
のインポートパス解決ロジックの正確性を保証するために非常に重要です。TestRepoRootForImportPath
関数は、様々なインポートパスに対してrepoRootForImportPath
関数を呼び出し、期待されるrepoRoot
(VCSの種類とリポジトリURL)が返されるか、または期待されるエラーが返されるかを検証します。
IBM DevOps Servicesに関するテストケースは、以下のシナリオをカバーしています。
- 正常系:
"hub.jazz.net/git/user1/pkgname"
: 基本的なリポジトリパスが正しくGitリポジトリとして認識され、正しいHTTPS URLが生成されることを確認します。"hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule"
: サブディレクトリを含むパスでも、リポジトリのルートが正しく特定されることを確認します。"hub.jazz.net/git/user/pkg.name"
: パッケージ名にドットが含まれる場合でも正しく解決されることを確認します。
- 異常系(エラーが期待されるケース):
"hub.jazz.net"
: リポジトリ名が不足しているため、エラーが期待されます。"hub2.jazz.net"
: ドメインが異なるため、エラーが期待されます。"hub.jazz.net/someotherprefix"
: プレフィックスがhub.jazz.net/git
ではないため、エラーが期待されます。"hub.jazz.net/git/User 1/pkgname"
: ユーザー名にスペースが含まれるため、正規表現にマッチせずエラーが期待されます。"hub.jazz.net/git/user1/pkg name"
: パッケージ名にスペースが含まれるため、正規表現にマッチせずエラーが期待されます。"hub.jazz.net/git/user.1/pkgname"
: ユーザー名にドットが含まれるため、正規表現にマッチせずエラーが期待されます。"hub.jazz.net/git/USER/pkgname"
: ユーザー名に大文字が含まれるため、正規表現にマッチせずエラーが期待されます。
これらのテストケースは、go get
がIBM DevOps Servicesのインポートパスを正確かつ堅牢に処理できることを保証するために不可欠です。
関連リンク
- Go Gerrit Change-ID: https://golang.org/cl/106740044
参考にした情報源リンク
- Go Command Documentation (go get): https://pkg.go.dev/cmd/go#hdr-Download_and_install_packages_and_dependencies
- IBM DevOps Services (JazzHub) についての一般的な情報 (当時のサービスに関する情報):
- https://www.ibm.com/cloud/garage/content/experience/devops-services/ (現在のIBM Cloud Garageのページですが、当時のサービスについても言及があります)
- https://www.ibm.com/developerworks/library/d-jazzhub-go-app/index.html (IBM DeveloperWorksの記事で、JazzHubとGoアプリケーションに関するもの。当時の状況を理解するのに役立ちます。)
- Go言語の正規表現に関するドキュメント: https://pkg.go.dev/regexp
- Go言語のテストに関するドキュメント: https://pkg.go.dev/testing