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

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

このコミットは、Go言語のドキュメント生成ツールである tmpltohtml に機能追加を行い、生成されるHTMLファイルに自動的に「DO NOT EDIT」という警告コメントを挿入するように変更したものです。これにより、生成されたファイルを誤って手動で編集してしまうことを防ぎ、テンプレートからの自動生成であることを明確に示します。

コミット

commit 1ddedbae316b90a50f17d8d7e8e726755a5dd26a
Author: Rob Pike <r@golang.org>
Date:   Thu Dec 8 11:26:49 2011 -0800

    tmpltohtml: put a DO NOT EDIT mark automatically in the output
    
    R=r, rsc, r
    CC=golang-dev
    https://golang.org/cl/5469045

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

https://github.com/golang/go/commit/1ddedbae316b90a50f17d8d7e8e726755a5dd26a

元コミット内容

tmpltohtml: put a DO NOT EDIT mark automatically in the output

このコミットは、tmpltohtml ツールが生成するHTMLファイルに、自動的に「DO NOT EDIT」というマークを挿入する機能を追加します。

変更の背景

Go言語の公式ドキュメント(例: Effective Go, Go Tutorial)は、Goの text/template パッケージを使用してテンプレートファイル(.tmpl)からHTMLファイル(.html)を生成する tmpltohtml というツールによって作成されていました。

このような自動生成されたファイルは、通常、手動で編集すべきではありません。なぜなら、テンプレートファイルが更新されるたびに、手動で行われた変更は上書きされてしまうためです。しかし、生成されたファイルを見ただけでは、それが自動生成されたものなのか、手動で編集可能なものなのかが区別しにくいという問題がありました。

このコミットの背景には、生成されたHTMLファイルが手動で編集されることを防ぎ、開発者が誤って時間を無駄にしたり、変更が失われたりするリスクを排除したいという意図があります。生成されたファイルに明示的な警告マークを挿入することで、そのファイルの性質を明確にし、適切なワークフローを促すことが目的です。

前提知識の解説

Go言語の text/template パッケージ

Go言語の標準ライブラリには、テキストベースのテンプレートを扱うための text/template パッケージが含まれています。このパッケージは、プレースホルダーや制御構造(条件分岐、ループなど)を含むテンプレート文字列を解析し、データに基づいて最終的なテキストを生成するために使用されます。

  • テンプレートの定義: テンプレートは、{{.FieldName}} のようなアクション(プレースホルダー)を含むテキストです。
  • template.New(): 新しいテンプレートインスタンスを作成します。
  • tmpl.ParseFiles(): 1つまたは複数のファイルからテンプレートを解析します。
  • template.FuncMap: テンプレート内で呼び出すことができるカスタム関数を登録するためのマップです。FuncMap を使用すると、Goの関数をテンプレート内で利用できるようになり、テンプレートの表現力を高めることができます。例えば、{{myCustomFunc .Data}} のようにテンプレート内でGoの関数を呼び出すことが可能になります。
  • tmpl.Execute(): 解析されたテンプレートにデータを適用し、結果を io.Writer に書き出します。

コード生成と「DO NOT EDIT」マーク

ソフトウェア開発において、コード生成は一般的なプラクティスです。APIクライアント、データモデル、設定ファイル、ドキュメントなど、様々なものが自動生成されます。自動生成されたファイルは、通常、その生成元となる定義ファイル(スキーマ、テンプレートなど)を編集することで変更されるべきであり、生成されたファイルを直接編集することは推奨されません。

「DO NOT EDIT」や「GENERATED CODE」といったマークは、このような自動生成されたファイルの冒頭に挿入される慣習的なコメントです。これにより、そのファイルが手動で編集されるべきではないことを開発者に明確に伝え、誤った変更を防ぎます。これは、コードベースの整合性を保ち、開発ワークフローを効率化するために非常に重要です。

技術的詳細

このコミットは、tmpltohtml ツールがGoの text/template パッケージを利用してHTMLファイルを生成する際に、新しいカスタムテンプレート関数 donotedit を導入することで、「DO NOT EDIT」マークを自動的に挿入する仕組みを実装しています。

  1. tmpltohtml.go の変更:

    • templateFuncs という新しい template.FuncMap が定義されました。このマップには、既存の code 関数に加えて、新しく追加された donotedit 関数が登録されます。
    • テンプレートの初期化時に、template.New(name).Funcs(templateFuncs) を使用して、この templateFuncs マップがテンプレートエンジンに渡されるようになりました。これにより、テンプレート内で {{donotedit}} というアクションが呼び出された際に、対応するGoの donotedit 関数が実行されるようになります。
    • donotedit() という新しいGo関数が追加されました。この関数は、fmt.Sprintf を使用して、生成元のテンプレートファイル名を含むHTMLコメント形式の文字列を返します。このコメントは、生成されたHTMLファイルの冒頭に挿入される「DO NOT EDIT」警告となります。
  2. テンプレートファイル(.tmpl)の変更:

    • doc/effective_go.tmpldoc/go_tutorial.tmpl の両方に、ファイルの冒頭に {{donotedit}} というテンプレートアクションが追加されました。これにより、tmpltohtml がこれらのテンプレートを処理する際に、donotedit 関数が呼び出され、その戻り値(「DO NOT EDIT」コメント)が生成されるHTMLファイルに挿入されるようになります。
  3. 生成されるHTMLファイル(.html)の変更:

    • doc/effective_go.htmldoc/go_tutorial.html に、tmpltohtml ツールによって生成されたことを示す「DO NOT EDIT」コメントブロックが追加されました。このコメントは、tmpltohtmleffective_go.tmplgo_tutorial.tmpl を処理した結果として挿入されます。

この一連の変更により、tmpltohtml を実行するだけで、生成されるHTMLファイルに自動的に警告コメントが埋め込まれるようになり、手動編集の防止とファイルの性質の明確化が実現されました。

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

このコミットのコアとなる変更は、doc/tmpltohtml.go ファイルにあります。

--- a/doc/tmpltohtml.go
+++ b/doc/tmpltohtml.go
@@ -35,6 +35,11 @@ func Usage() {
 	os.Exit(2)
 }
 
+var templateFuncs = template.FuncMap{
+	"code":      code,
+	"donotedit": donotedit,
+}
+
 func main() {
 	flag.Usage = Usage
 	flag.Parse()
@@ -44,7 +49,7 @@ func main() {
 
 	// Read and parse the input.
 	name := flag.Args()[0]
-	tmpl := template.New(name).Funcs(template.FuncMap{"code": code})
+	tmpl := template.New(name).Funcs(templateFuncs)
 	if _, err := tmpl.ParseFiles(name); err != nil {
 		log.Fatal(err)
 	}
@@ -80,6 +85,11 @@ func format(arg interface{}) string {
 	return ""
 }
 
+func donotedit() string {
+	// No editing please.
+	return fmt.Sprintf("<!--\\n  DO NOT EDIT: created by\\n    tmpltohtml %s\\n-->\\n", flag.Args()[0])
+}
+
 func code(file string, arg ...interface{}) (string, error) {
 	text := contents(file)
 	var command string

また、テンプレートファイルにも変更が加えられています。

doc/effective_go.tmpl の変更:

--- a/doc/effective_go.tmpl
+++ b/doc/effective_go.tmpl
@@ -1,4 +1,5 @@
 <!-- Effective Go -->
+{{donotedit}}
 
 <h2 id="introduction">Introduction</h2>
 

doc/go_tutorial.tmpl の変更:

--- a/doc/go_tutorial.tmpl
+++ b/doc/go_tutorial.tmpl
@@ -1,4 +1,6 @@
 <!-- A Tutorial for the Go Programming Language -->
+{{donotedit}}
+
 <h2>Introduction</h2>
 <p>
 This document is a tutorial introduction to the basics of the Go programming

コアとなるコードの解説

doc/tmpltohtml.go

  1. templateFuncs の定義:

    var templateFuncs = template.FuncMap{
    	"code":      code,
    	"donotedit": donotedit,
    }
    

    templateFuncstemplate.FuncMap 型の変数で、テンプレート内で使用できるカスタム関数を登録するために使われます。ここでは、既存の code 関数に加えて、新しく定義された donotedit 関数が "donotedit" という名前で登録されています。これにより、テンプレート内で {{donotedit}} と記述することで、Goの donotedit 関数が呼び出されるようになります。

  2. テンプレートエンジンへの templateFuncs の適用:

    // 変更前: tmpl := template.New(name).Funcs(template.FuncMap{"code": code})
    tmpl := template.New(name).Funcs(templateFuncs)
    

    template.New(name).Funcs() メソッドは、テンプレートエンジンにカスタム関数マップを適用します。変更前は code 関数のみを含む匿名 FuncMap を直接渡していましたが、変更後は templateFuncs 変数を渡すことで、codedonotedit の両方の関数がテンプレートから利用可能になります。

  3. donotedit() 関数の実装:

    func donotedit() string {
    	// No editing please.
    	return fmt.Sprintf("<!--\\n  DO NOT EDIT: created by\\n    tmpltohtml %s\\n-->\\n", flag.Args()[0])
    }
    

    この関数は、テンプレートから呼び出されると、HTMLコメント形式の文字列を生成して返します。

    • <!-- ... --> はHTMLのコメント構文です。
    • \n は改行文字です。
    • DO NOT EDIT: created by は、このファイルが自動生成されたものであることを明確に示します。
    • tmpltohtml %s%s には、flag.Args()[0] の値、つまり tmpltohtml コマンドの引数として渡された元のテンプレートファイル名(例: effective_go.tmpl)が挿入されます。これにより、どのテンプレートから生成されたファイルであるかが一目でわかるようになります。

テンプレートファイル (.tmpl)

doc/effective_go.tmpldoc/go_tutorial.tmpl の冒頭に {{donotedit}} が追加されました。 これは、tmpltohtml がこれらのテンプレートを処理する際に、donotedit 関数を呼び出し、その結果(「DO NOT EDIT」コメント)を生成されるHTMLファイルの対応する位置に挿入するように指示するものです。

これらの変更により、tmpltohtml ツールは、生成されるHTMLファイルの冒頭に、そのファイルが自動生成されたものであり、手動で編集すべきではないことを示す明確な警告コメントを自動的に含めるようになりました。

関連リンク

  • Gerrit Change-ID: https://golang.org/cl/5469045 このリンクは、GoプロジェクトのコードレビューシステムであるGerritにおけるこのコミットの変更セットを示しています。通常、ここには変更に関する議論や追加のコンテキストが含まれています。

参考にした情報源リンク

  • GitHubコミットページ
  • Go言語 text/template パッケージのドキュメント (Goの公式ドキュメントを参照)
  • コード生成に関する一般的なプラクティス (一般的なソフトウェアエンジニアリングの知識)
  • tmpltohtml ツールのソースコード (doc/tmpltohtml.go)
  • Go言語のドキュメントテンプレート (doc/effective_go.tmpl, doc/go_tutorial.tmpl)# [インデックス 10666] ファイルの概要

このコミットは、Go言語のドキュメント生成ツールである tmpltohtml に機能追加を行い、生成されるHTMLファイルに自動的に「DO NOT EDIT」という警告コメントを挿入するように変更したものです。これにより、生成されたファイルを誤って手動で編集してしまうことを防ぎ、テンプレートからの自動生成であることを明確に示します。

コミット

commit 1ddedbae316b90a50f17d8d7e8e726755a5dd26a
Author: Rob Pike <r@golang.org>
Date:   Thu Dec 8 11:26:49 2011 -0800

    tmpltohtml: put a DO NOT EDIT mark automatically in the output
    
    R=r, rsc, r
    CC=golang-dev
    https://golang.org/cl/5469045

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

https://github.com/golang/go/commit/1ddedbae316b90a50f17d8d7e8e726755a5dd26a

元コミット内容

tmpltohtml: put a DO NOT EDIT mark automatically in the output

このコミットは、tmpltohtml ツールが生成するHTMLファイルに、自動的に「DO NOT EDIT」というマークを挿入する機能を追加します。

変更の背景

Go言語の公式ドキュメント(例: Effective Go, Go Tutorial)は、Goの text/template パッケージを使用してテンプレートファイル(.tmpl)からHTMLファイル(.html)を生成する tmpltohtml というツールによって作成されていました。

このような自動生成されたファイルは、通常、手動で編集すべきではありません。なぜなら、テンプレートファイルが更新されるたびに、手動で行われた変更は上書きされてしまうためです。しかし、生成されたファイルを見ただけでは、それが自動生成されたものなのか、手動で編集可能なものなのかが区別しにくいという問題がありました。

このコミットの背景には、生成されたHTMLファイルが手動で編集されることを防ぎ、開発者が誤って時間を無駄にしたり、変更が失われたりするリスクを排除したいという意図があります。生成されたファイルに明示的な警告マークを挿入することで、そのファイルの性質を明確にし、適切なワークフローを促すことが目的です。

前提知識の解説

Go言語の text/template パッケージ

Go言語の標準ライブラリには、テキストベースのテンプレートを扱うための text/template パッケージが含まれています。このパッケージは、プレースホルダーや制御構造(条件分岐、ループなど)を含むテンプレート文字列を解析し、データに基づいて最終的なテキストを生成するために使用されます。

  • テンプレートの定義: テンプレートは、{{.FieldName}} のようなアクション(プレースホルダー)を含むテキストです。
  • template.New(): 新しいテンプレートインスタンスを作成します。
  • tmpl.ParseFiles(): 1つまたは複数のファイルからテンプレートを解析します。
  • template.FuncMap: テンプレート内で呼び出すことができるカスタム関数を登録するためのマップです。FuncMap を使用すると、Goの関数をテンプレート内で利用できるようになり、テンプレートの表現力を高めることができます。例えば、{{myCustomFunc .Data}} のようにテンプレート内でGoの関数を呼び出すことが可能になります。
  • tmpl.Execute(): 解析されたテンプレートにデータを適用し、結果を io.Writer に書き出します。

コード生成と「DO NOT EDIT」マーク

ソフトウェア開発において、コード生成は一般的なプラクティスです。APIクライアント、データモデル、設定ファイル、ドキュメントなど、様々なものが自動生成されます。自動生成されたファイルは、通常、その生成元となる定義ファイル(スキーマ、テンプレートなど)を編集することで変更されるべきであり、生成されたファイルを直接編集することは推奨されません。

「DO NOT EDIT」や「GENERATED CODE」といったマークは、このような自動生成されたファイルの冒頭に挿入される慣習的なコメントです。これにより、そのファイルが手動で編集されるべきではないことを開発者に明確に伝え、誤った変更を防ぎます。これは、コードベースの整合性を保ち、開発ワークフローを効率化するために非常に重要です。

技術的詳細

このコミットは、tmpltohtml ツールがGoの text/template パッケージを利用してHTMLファイルを生成する際に、新しいカスタムテンプレート関数 donotedit を導入することで、「DO NOT EDIT」マークを自動的に挿入する仕組みを実装しています。

  1. tmpltohtml.go の変更:

    • templateFuncs という新しい template.FuncMap が定義されました。このマップには、既存の code 関数に加えて、新しく追加された donotedit 関数が登録されます。
    • テンプレートの初期化時に、template.New(name).Funcs(templateFuncs) を使用して、この templateFuncs マップがテンプレートエンジンに渡されるようになりました。これにより、テンプレート内で {{donotedit}} というアクションが呼び出された際に、対応するGoの donotedit 関数が実行されるようになります。
    • donotedit() という新しいGo関数が追加されました。この関数は、fmt.Sprintf を使用して、生成元のテンプレートファイル名を含むHTMLコメント形式の文字列を返します。このコメントは、生成されたHTMLファイルの冒頭に挿入される「DO NOT EDIT」警告となります。
  2. テンプレートファイル(.tmpl)の変更:

    • doc/effective_go.tmpldoc/go_tutorial.tmpl の両方に、ファイルの冒頭に {{donotedit}} というテンプレートアクションが追加されました。これにより、tmpltohtml がこれらのテンプレートを処理する際に、donotedit 関数が呼び出され、その戻り値(「DO NOT EDIT」コメント)が生成されるHTMLファイルに挿入されるようになります。
  3. 生成されるHTMLファイル(.html)の変更:

    • doc/effective_go.htmldoc/go_tutorial.html に、tmpltohtml ツールによって生成されたことを示す「DO NOT EDIT」コメントブロックが追加されました。このコメントは、tmpltohtmleffective_go.tmplgo_tutorial.tmpl を処理した結果として挿入されます。

この一連の変更により、tmpltohtml を実行するだけで、生成されるHTMLファイルに自動的に警告コメントが埋め込まれるようになり、手動編集の防止とファイルの性質の明確化が実現されました。

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

このコミットのコアとなる変更は、doc/tmpltohtml.go ファイルにあります。

--- a/doc/tmpltohtml.go
+++ b/doc/tmpltohtml.go
@@ -35,6 +35,11 @@ func Usage() {
 	os.Exit(2)
 }
 
+var templateFuncs = template.FuncMap{
+	"code":      code,
+	"donotedit": donotedit,
+}
+
 func main() {
 	flag.Usage = Usage
 	flag.Parse()
@@ -44,7 +49,7 @@ func main() {
 
 	// Read and parse the input.
 	name := flag.Args()[0]
-	tmpl := template.New(name).Funcs(template.FuncMap{"code": code})
+	tmpl := template.New(name).Funcs(templateFuncs)
 	if _, err := tmpl.ParseFiles(name); err != nil {
 		log.Fatal(err)
 	}
@@ -80,6 +85,11 @@ func format(arg interface{}) string {
 	return ""
 }
 
+func donotedit() string {
+	// No editing please.
+	return fmt.Sprintf("<!--\\n  DO NOT EDIT: created by\\n    tmpltohtml %s\\n-->\\n", flag.Args()[0])
+}
+
 func code(file string, arg ...interface{}) (string, error) {
 	text := contents(file)
 	var command string

また、テンプレートファイルにも変更が加えられています。

doc/effective_go.tmpl の変更:

--- a/doc/effective_go.tmpl
+++ b/doc/effective_go.tmpl
@@ -1,4 +1,5 @@
 <!-- Effective Go -->
+{{donotedit}}
 
 <h2 id="introduction">Introduction</h2>
 

doc/go_tutorial.tmpl の変更:

--- a/doc/go_tutorial.tmpl
+++ b/doc/go_tutorial.tmpl
@@ -1,4 +1,6 @@
 <!-- A Tutorial for the Go Programming Language -->
+{{donotedit}}
+
 <h2>Introduction</h2>
 <p>
 This document is a tutorial introduction to the basics of the Go programming

コアとなるコードの解説

doc/tmpltohtml.go

  1. templateFuncs の定義:

    var templateFuncs = template.FuncMap{
    	"code":      code,
    	"donotedit": donotedit,
    }
    

    templateFuncstemplate.FuncMap 型の変数で、テンプレート内で使用できるカスタム関数を登録するために使われます。ここでは、既存の code 関数に加えて、新しく定義された donotedit 関数が "donotedit" という名前で登録されています。これにより、テンプレート内で {{donotedit}} と記述することで、Goの donotedit 関数が呼び出されるようになります。

  2. テンプレートエンジンへの templateFuncs の適用:

    // 変更前: tmpl := template.New(name).Funcs(template.FuncMap{"code": code})
    tmpl := template.New(name).Funcs(templateFuncs)
    

    template.New(name).Funcs() メソッドは、テンプレートエンジンにカスタム関数マップを適用します。変更前は code 関数のみを含む匿名 FuncMap を直接渡していましたが、変更後は templateFuncs 変数を渡すことで、codedonotedit の両方の関数がテンプレートから利用可能になります。

  3. donotedit() 関数の実装:

    func donotedit() string {
    	// No editing please.
    	return fmt.Sprintf("<!--\\n  DO NOT EDIT: created by\\n    tmpltohtml %s\\n-->\\n", flag.Args()[0])
    }
    

    この関数は、テンプレートから呼び出されると、HTMLコメント形式の文字列を生成して返します。

    • <!-- ... --> はHTMLのコメント構文です。
    • \n は改行文字です。
    • DO NOT EDIT: created by は、このファイルが自動生成されたものであることを明確に示します。
    • tmpltohtml %s%s には、flag.Args()[0] の値、つまり tmpltohtml コマンドの引数として渡された元のテンプレートファイル名(例: effective_go.tmpl)が挿入されます。これにより、どのテンプレートから生成されたファイルであるかが一目でわかるようになります。

テンプレートファイル (.tmpl)

doc/effective_go.tmpldoc/go_tutorial.tmpl の冒頭に {{donotedit}} が追加されました。 これは、tmpltohtml がこれらのテンプレートを処理する際に、donotedit 関数を呼び出し、その結果(「DO NOT EDIT」コメント)を生成されるHTMLファイルの対応する位置に挿入するように指示するものです。

これらの変更により、tmpltohtml ツールは、生成されるHTMLファイルの冒頭に、そのファイルが自動生成されたものであり、手動で編集すべきではないことを示す明確な警告コメントを自動的に含めるようになりました。

関連リンク

  • Gerrit Change-ID: https://golang.org/cl/5469045 このリンクは、GoプロジェクトのコードレビューシステムであるGerritにおけるこのコミットの変更セットを示しています。通常、ここには変更に関する議論や追加のコンテキストが含まれています。

参考にした情報源リンク

  • GitHubコミットページ
  • Go言語 text/template パッケージのドキュメント (Goの公式ドキュメントを参照)
  • コード生成に関する一般的なプラクティス (一般的なソフトウェアエンジニアリングの知識)
  • tmpltohtml ツールのソースコード (doc/tmpltohtml.go)
  • Go言語のドキュメントテンプレート (doc/effective_go.tmpl, doc/go_tutorial.tmpl)