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

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

このコミットは、Go言語のコマンドラインツール cmd/go におけるバージョン管理システム (VCS) のパス解決ロジック、特に code.google.com からクローンされたリポジトリの処理に関する修正です。具体的には、code.google.com のリポジトリパスを解析するための正規表現が更新され、p/ だけでなく r/ というプレフィックスも正しく認識できるように変更されました。

コミット

commit 65f21ca2c6e62cc9fb77a285764420df9e7f248f
Author: Rob Pike <r@golang.org>
Date:   Thu Aug 29 17:15:35 2013 +1000

    cmd/go: make it work for code.google.com cloned repositories
    
    Thanks to beatgammit for the fix.
    
    Fixes #5408.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/13261048

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

https://github.com/golang/go/commit/65f21ca2c6e62cc9fb77a285764420df9e7f248f

元コミット内容

cmd/go: make it work for code.google.com cloned repositories

このコミットは、code.google.com からクローンされたリポジトリが go get コマンドで正しく動作するようにするためのものです。beatgammit 氏による修正が取り入れられています。

変更の背景

Go言語の go get コマンドは、指定されたパスからソースコードを自動的にダウンロードし、ビルドするための非常に便利なツールです。このコマンドは、GitHub、Bitbucket、Launchpad、そしてかつては code.google.com など、様々なバージョン管理システムホスティングサービスをサポートしていました。

code.google.com は、Googleが提供していたオープンソースプロジェクトホスティングサービスで、多くのGoプロジェクトもそこでホストされていました。Goのツールチェーンは、これらのサービスからリポジトリを識別し、適切なVCSコマンド(Git、Mercurial、Subversionなど)を使用してクローンできるように、内部に特定のパスパターンと正規表現を持っていました。

このコミットが行われた2013年当時、code.google.com のリポジトリパスの構造に変化があったか、あるいは既存の正規表現が特定の有効なパス形式をカバーしていなかった可能性があります。具体的には、code.google.com/p/projectname のようなパスが一般的でしたが、何らかの理由で code.google.com/r/projectname のようなパスも存在し、それが go get で正しく認識されない問題が発生していました。

コミットメッセージにある Fixes #5408 は、この変更がGoのIssueトラッカーで報告された特定のバグを修正するものであることを示しています。Issue #5408の内容を確認すると、code.google.com のリポジトリパスの正規表現が p/ のみを想定しており、r/ を含むパスを処理できないという問題が報告されていました。これは、code.google.com が内部的にリポジトリの参照方法を変更したか、あるいはGoツールが当初からそのバリエーションを考慮していなかったためと考えられます。

前提知識の解説

  • go get コマンド: Go言語のパッケージ管理ツールの一部で、リモートリポジトリからGoパッケージのソースコードを取得し、ローカルの GOPATH に配置するコマンドです。依存関係の解決にも利用されます。
  • バージョン管理システム (VCS): Git、Mercurial (hg)、Subversion (svn) など、ソースコードの変更履歴を管理するためのシステムです。go get は、リポジトリのURLから使用されているVCSを自動的に判別します。
  • 正規表現 (Regular Expression): 文字列のパターンを記述するための強力な記法です。このコミットでは、code.google.com のリポジトリURLが特定のパターンに一致するかどうかを検証するために使用されています。
    • ^: 文字列の先頭にマッチします。
    • $: 文字列の末尾にマッチします。
    • (?P<name>...): 名前付きキャプチャグループです。マッチした部分文字列に name という名前を付けて後で参照できるようにします。
    • [a-z0-9\\-]+: 小文字の英字、数字、ハイフンが1回以上繰り返されるパターンにマッチします。
    • \.: ドット文字そのものにマッチします(ドットは正規表現で特殊文字なのでエスケープが必要です)。
    • ?: 直前の要素が0回または1回出現することにマッチします。
    • *: 直前の要素が0回以上出現することにマッチします。
    • [pr]: p または r のいずれか一文字にマッチします。これはこのコミットの核心部分です。
  • src/cmd/go/vcs.go: Goツールチェーンのソースコード内で、go get コマンドが様々なVCSホスティングサービスのリポジトリパスをどのように解析し、対応するVCSコマンドを呼び出すかを定義しているファイルです。このファイルには、各サービスのURLパターンと、それに対応する正規表現や処理ロジックが記述されています。
  • vcsPaths: vcs.go 内で定義されている、既知のVCSホスティングサービスのパスパターンとそれに対応する正規表現、およびチェック関数を格納するスライス(Goにおける動的配列)です。go get は、与えられたインポートパスをこのリストのパターンと照合し、適切なVCSを特定します。

技術的詳細

このコミットの技術的詳細は、src/cmd/go/vcs.go ファイル内の vcsPaths スライスに定義されている code.google.com 用のエントリの正規表現の変更に集約されます。

元の正規表現は以下の通りでした。 ^(?P<root>code\\.google\\.com/p/(?P<project>[a-z0-9\\-]+)(\\.(?P<subrepo>[a-z0-9\\-]+))?)(/[A-Za-z0-9_.\\-]+)*$

この正規表現の重要な部分は code\\.google\\.com/p/ です。これは、code.google.com の直後に /p/ が続くパスのみを code.google.com のリポジトリとして認識することを意味していました。

しかし、code.google.com のリポジトリパスには、p/ だけでなく r/ というプレフィックスも存在することが判明しました。例えば、https://code.google.com/p/go のようなパスと並んで、https://code.google.com/r/go のようなパスも有効であった可能性があります。既存の正規表現では /r/ を含むパスはマッチせず、go get がリポジトリを正しくクローンできない問題を引き起こしていました。

この問題を解決するため、正規表現の /p/ の部分が / の後に p または r のいずれか一文字にマッチする [pr] に変更されました。

変更後の正規表現は以下の通りです。 ^(?P<root>code\\.google\\.com/[pr]/(?P<project>[a-z0-9\\-]+)(\\.(?P<subrepo>[a-z0-9\\-]+))?)(/[A-Za-z0-9_.\\-]+)*$

この変更により、code.google.com/p/projectnamecode.google.com/r/projectname の両方の形式のパスが go get によって正しく認識され、処理されるようになりました。これは、Goツールチェーンが外部のサービスの変化に柔軟に対応し、ユーザーがGoパッケージをより広範なソースから取得できるようにするための重要な修正でした。

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

--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -569,7 +569,7 @@ var vcsPaths = []*vcsPath{
 	// Google Code - new syntax
 	{\n 		prefix: "code.google.com/",
-\t\tre:     `^(?P<root>code\\.google\\.com/p/(?P<project>[a-z0-9\\-]+)(\\.(?P<subrepo>[a-z0-9\\-]+))?)(/[A-Za-z0-9_.\\-]+)*$`,\n+\t\tre:     `^(?P<root>code\\.google\\.com/[pr]/(?P<project>[a-z0-9\\-]+)(\\.(?P<subrepo>[a-z0-9\\-]+))?)(/[A-Za-z0-9_.\\-]+)*$`,\n \t\trepo:   "https://{root}",
 \t\tcheck:  googleCodeVCS,
 \t},

コアとなるコードの解説

変更は src/cmd/go/vcs.go ファイル内の vcsPaths スライスにある、code.google.com 用の vcsPath エントリの正規表現 (re フィールド) にあります。

  • prefix: "code.google.com/": このエントリが code.google.com/ で始まるパスに適用されることを示します。
  • re: ...: ここが正規表現の定義です。
    • 変更前: code\\.google\\.com/p/
    • 変更後: code\\.google\\.com/[pr]/ この変更により、正規表現は code.google.com/ の後に p または r のいずれかの文字が続き、その後に / が続くパターンにマッチするようになります。これにより、code.google.com/p/code.google.com/r/ の両方のパス形式が正しく認識されるようになりました。
  • repo: "https://{root}": マッチしたパスの root 部分(正規表現の名前付きキャプチャグループ (?P<root>...) で定義された部分)を使用して、リポジトリのクローンURLを構築する方法を示します。
  • check: googleCodeVCS: このパスが code.google.com のリポジトリであるかどうかをさらに検証するための関数です。

この修正は、Goツールチェーンの堅牢性を高め、特定の外部サービス(この場合は code.google.com)のURL構造のわずかなバリエーションにも対応できるようにすることで、ユーザーエクスペリエンスを向上させました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (特に go get コマンドに関する部分)
  • 正規表現の一般的なリファレンス
  • code.google.com の歴史とGoプロジェクトのホスティングに関する情報 (サービスは終了していますが、当時の状況を理解するために参照)
  • Go言語のソースコード (src/cmd/go/vcs.go の当時のバージョン)