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

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

このコミットは、Go言語のドキュメンテーションツールであるgodocのコードベースに対する変更です。具体的には、appinit.goファイル内のエラーハンドリングロジックを更新し、main.goファイルに!appengineビルド制約を適用することで、godocがGoogle App Engine環境でビルドされないように調整しています。これにより、godocのビルドプロセスがより明確になり、App Engineとの競合が回避されます。

コミット

  • コミットハッシュ: 96da953d86130b1d9779538c2a09d3b58e69c0f1
  • 作者: Shenghou Ma minux.ma@gmail.com
  • コミット日時: 2012年4月4日(水) 00:00:26 +0800
  • コミットメッセージ:
    godoc: update appinit.go, apply !appengine build constrain to main.go
    
    R=adg, dsymonds
    CC=golang-dev
    https://golang.org/cl/5969063
    

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

https://github.com/golang/go/commit/96da953d86130b1d9779538c2a09d3b58e69c0f1

元コミット内容

godoc: update appinit.go, apply !appengine build constrain to main.go

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

変更の背景

この変更の背景には、godocツールがGoogle App Engine (GAE) 環境で意図せずビルドされることを防ぐ目的があります。godocはGo言語のソースコードからドキュメンテーションを生成し、HTTPサーバーとして提供するツールであり、通常は開発者のローカル環境やCI/CDパイプラインで利用されます。一方、Google App EngineはWebアプリケーションをホストするためのプラットフォームであり、特定の制約やランタイム環境を持っています。

godocの機能はApp Engineのサンドボックス環境とは相性が悪く、またApp Engine上でgodocを直接実行するユースケースも一般的ではありませんでした。そのため、godocmainパッケージがApp Engine環境でビルドされないように明示的なビルド制約を追加し、同時にエラーページ表示の内部的な構造を改善することで、コードの整合性と保守性を高めることが目的とされています。

前提知識の解説

godoc

godocは、Go言語の公式ドキュメンテーションツールです。Goのソースコードに記述されたコメント(特にエクスポートされた識別子に付随するコメント)を解析し、HTML形式で整形されたドキュメンテーションを生成します。また、ローカルでHTTPサーバーを起動し、ブラウザを通じてドキュメンテーションを閲覧できる機能も提供します。これはGo言語の「ドキュメンテーションはコードの一部である」という哲学を体現する重要なツールです。

Google App Engine (GAE)

Google App Engineは、Googleが提供するPlatform as a Service (PaaS) です。開発者はアプリケーションのコードをデプロイするだけで、インフラストラクチャの管理をGoogleに任せることができます。App Engineは、Goを含む複数の言語をサポートしており、スケーラビリティ、信頼性、セキュリティに優れたWebアプリケーションのホスティングを提供します。しかし、App Engineのサンドボックス環境には、ファイルシステムへのアクセス制限や特定のネットワーク操作の制限など、通常のOS環境とは異なる制約があります。

Goのビルド制約 (Build Constraints)

Go言語には、特定のファイルが特定の環境でのみコンパイルされるように制御するための「ビルド制約(Build Constraints)」というメカニズムがあります。これは、ソースファイルの先頭に// +build tagのような形式で記述されます。

  • // +build tag: このタグが指定された場合、Goコンパイラは、ビルドコマンドでtagが有効になっている場合にのみそのファイルをコンパイルします。
  • // +build !tag: このタグが指定された場合、Goコンパイラは、ビルドコマンドでtagが有効になっていない場合にのみそのファイルをコンパイルします。

このコミットでは+build !appengineが使用されており、これは「appengineタグが有効になっていない場合にのみこのファイルをビルドする」という意味になります。つまり、App Engine環境でのビルド時にはこのファイルが除外されることになります。

技術的詳細

このコミットは、godocのビルドとエラー表示の2つの側面で技術的な変更を加えています。

  1. main.goへのビルド制約の適用: src/cmd/godoc/main.goファイルの先頭に// +build !appengineという行が追加されました。これにより、GoコンパイラがApp Engine環境向けにビルドされる際(例えば、goapp deployコマンドなどを使用する場合)、main.goファイルはコンパイル対象から除外されます。godocmainパッケージは、HTTPサーバーの起動やコマンドライン引数の解析など、App Engineのランタイムモデルとは異なる動作を前提としているため、この制約はgodocがApp Engine環境で誤ってビルドされることを防ぎ、ビルドエラーや予期せぬ動作を回避します。

  2. appinit.goのエラーハンドリングの改善: src/cmd/godoc/appinit.go内のserveError関数が変更されました。この関数は、ファイルが見つからないなどのエラーが発生した際にエラーページを生成してクライアントに返す役割を担っています。 変更前は、servePage関数に複数の引数を直接渡していましたが、変更後はPageという構造体(おそらく内部的に定義されている)を介して引数を渡すように修正されました。

    // 変更前
    // servePage(w, relpath, "File "+relpath, "", "", contents)
    
    // 変更後
    servePage(w, Page{
        Title:    "File " + relpath,
        Subtitle: relpath,
        Body:     applyTemplate(errorHTML, "errorHTML", err), // err may contain an absolute path!
    })
    

    この変更は、servePage関数への引数の渡し方をより構造化された形式にすることで、コードの可読性と保守性を向上させることを目的としています。Page構造体を使用することで、各引数の意味が明確になり、将来的に引数が増減した場合でも関数のシグネチャを変更することなく対応しやすくなります。また、servePage関数がより汎用的なページ表示ロジックを持つことを示唆しています。

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

diff --git a/src/cmd/godoc/appinit.go b/src/cmd/godoc/appinit.go
index 70da001100..a4ae40bf29 100644
--- a/src/cmd/godoc/appinit.go
+++ b/src/cmd/godoc/appinit.go
@@ -17,9 +17,12 @@ import (
 )

 func serveError(w http.ResponseWriter, r *http.Request, relpath string, err error) {
-	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
 	w.WriteHeader(http.StatusNotFound)
-	servePage(w, relpath, "File "+relpath, "", "", contents)
+	servePage(w, Page{
+		Title:    "File " + relpath,
+		Subtitle: relpath,
+		Body:     applyTemplate(errorHTML, "errorHTML", err), // err may contain an absolute path!
+	})
 }

 func init() {
diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go
index cb6e0530b9..3efa349b51 100644
--- a/src/cmd/godoc/main.go
+++ b/src/cmd/godoc/main.go
@@ -23,6 +23,8 @@
 //	godoc crypto/block Cipher NewCMAC
 //		- prints doc for Cipher and NewCMAC in package crypto/block

+// +build !appengine
+
 package main

 import (

コアとなるコードの解説

src/cmd/godoc/appinit.goの変更

serveError関数は、HTTPリクエストに対するエラー応答を生成する役割を担っています。 変更前は、エラーメッセージのコンテンツをapplyTemplateで生成した後、そのコンテンツと他のメタデータ(relpath、タイトルなど)を直接servePage関数に渡していました。

変更後は、servePage関数に渡す引数をPageという構造体のインスタンスとしてラップしています。

  • Title: "File " + relpath: ページのタイトルを設定します。
  • Subtitle: relpath: サブタイトルとして関連パスを設定します。
  • Body: applyTemplate(errorHTML, "errorHTML", err): エラーメッセージの本体をテンプレートから生成し、設定します。

この変更により、servePage関数の呼び出しがより明示的になり、各フィールドが何を表しているのかがコード上で一目瞭然になります。これは、関数の引数が多くなった場合に特に有効なリファクタリング手法であり、コードの保守性と理解度を高めます。

src/cmd/godoc/main.goの変更

src/cmd/godoc/main.goファイルのpackage main宣言の直前に、// +build !appengineという行が追加されました。 これはGoのビルド制約であり、このファイルがGoogle App Engine環境向けにビルドされる際にはコンパイル対象から除外されることを意味します。 godocは通常、スタンドアロンのアプリケーションとして動作し、ファイルシステムへのアクセスやネットワークポートのリスニングなど、App Engineのサンドボックス環境では制限される可能性のある操作を行います。このビルド制約を追加することで、godocmainパッケージがApp Engineのビルドプロセスに誤って含まれることを防ぎ、ビルドエラーやApp Engineのデプロイメントにおける問題を回避します。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメンテーション
  • Google App Engineの公式ドキュメンテーション
  • Go言語のビルド制約に関する一般的な情報源
  • コミットメッセージに記載されているGoのコードレビューシステム (Gerrit) のリンク: https://golang.org/cl/5969063 (現在はGoのGerritインスタンスは廃止され、GitHubに移行しています。このリンクは当時のレビューへの参照です。)