[インデックス 10867] ファイルの概要
このコミットは、Go言語プロジェクトのダッシュボードアプリケーションの一部であるmisc/dashboard/app/build/ui.go
とmisc/dashboard/app/build/ui.html
の2つのファイルを変更しています。
misc/dashboard/app/build/ui.go
: このファイルはGo言語で書かれており、ダッシュボードのビルドステータスページのUIロジックとデータ処理を担当しています。特に、HTMLテンプレートで使用されるカスタム関数(template.FuncMap
)の定義が含まれています。misc/dashboard/app/build/ui.html
: このファイルはHTMLテンプレートであり、ビルドステータスページの構造と表示を定義しています。Goのhtml/template
パッケージによってレンダリングされ、ui.go
で定義されたデータや関数を利用して動的なコンテンツを生成します。
これらのファイルは連携して、Goプロジェクトの様々なビルドのステータス(成功、失敗、コミット情報、ビルド時間など)をユーザーフレンドリーな形式で表示する役割を担っています。
コミット
commit 35755b9cdb14d81385be4377ee8666455aeba153
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Dec 19 16:57:25 2011 +1100
dashboard: improve formatting of build status page
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5493077
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/35755b9cdb14d81385be4377ee8666455aeba153
元コミット内容
dashboard: improve formatting of build status page
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5493077
変更の背景
このコミットの主な目的は、Goプロジェクトのダッシュボードにおけるビルドステータスページの表示を改善することです。具体的には、以下の点が課題として認識されていたと考えられます。
- 情報の冗長性: コミットのDescription(説明)やユーザー名が長すぎると、テーブルのレイアウトが崩れたり、視認性が低下したりする可能性があります。特にコミットDescriptionは複数行にわたることが多く、表示領域を圧迫します。
- 表示の一貫性: コミットハッシュやタイムスタンプのような技術的な情報は、等幅フォントで表示されることで視認性が向上し、他のコードやハッシュ値との比較が容易になります。しかし、これらが通常のフォントで表示されていると、読みにくさを感じることがあります。
- タイムスタンプのフォーマット: デフォルトのタイムスタンプ表示が、ユーザーにとって直感的でなかったり、必要な情報(日付と時刻)が適切に強調されていなかったりする可能性があります。
これらの課題を解決し、ビルドステータスページをよりユーザーフレンドリーで、情報を素早く把握しやすいようにするために、本コミットで表示の整形が行われました。
前提知識の解説
Go言語のhtml/template
パッケージ
Go言語のhtml/template
パッケージは、HTMLドキュメントを安全に生成するためのテンプレートエンジンを提供します。このパッケージは、クロスサイトスクリプティング(XSS)攻撃を防ぐための自動エスケープ機能を備えています。
- テンプレートのパース:
template.ParseFiles
やtemplate.Parse
などの関数を使って、テンプレートファイルを読み込み、パースします。 - データとの結合: パースされたテンプレートは、Goの構造体やマップなどのデータと結合(Execute)することで、動的なHTMLを生成します。
template.FuncMap
: テンプレート内で使用できるカスタム関数を定義するためのマップです。template.FuncMap
にGoの関数を登録することで、HTMLテンプレート内からその関数を呼び出し、データの整形や加工を行うことができます。これにより、プレゼンテーションロジックの一部をGoコードにカプセル化し、テンプレートの可読性を高めることができます。
Go言語のtime
パッケージとFormat
メソッド
Go言語のtime
パッケージは、時刻の表現、測定、表示に関する機能を提供します。
time.Time
型: 特定の時点を表す型です。Format
メソッド:time.Time
型のメソッドで、時刻を指定されたレイアウト文字列に従ってフォーマットします。Goのtime.Format
メソッドは、他の言語でよく見られるようなYYYY-MM-DD
のような記号ベースのフォーマット文字列ではなく、リファレンス時刻(Mon Jan 2 15:04:05 MST 2006
、または01/02 03:04:05PM '06 -0700
)を例として使用します。このリファレンス時刻の各要素(月、日、時など)が、出力したい時刻の対応する要素に置き換えられます。- 例:
t.Format("02 Jan 2006 15:04")
は、02
が日、Jan
が月、2006
が年、15
が時(24時間形式)、04
が分に対応します。
- 例:
CSSのfont-family: monospace
CSSのfont-family
プロパティは、要素に適用するフォントを指定します。monospace
は、等幅フォント(monospaced font)を指定するジェネリックファミリーキーワードです。等幅フォントでは、すべての文字が同じ幅を持つため、コード、ハッシュ値、タイムスタンプなど、文字の整列が重要な情報を表示する際に非常に役立ちます。これにより、視認性が向上し、桁の比較などが容易になります。
Goプロジェクトのダッシュボード
Goプロジェクトは、継続的インテグレーション(CI)システムを使用して、様々なプラットフォームや構成でのビルドとテストのステータスを監視しています。このダッシュボードは、これらのビルド結果を一元的に表示し、開発者がプロジェクトの健全性を迅速に確認できるようにするためのウェブインターフェースです。通常、Goのバックエンド(ui.go
のようなファイル)がデータを処理し、HTMLテンプレート(ui.html
のようなファイル)がそのデータを整形してブラウザに表示します。
技術的詳細
このコミットでは、Goのhtml/template
パッケージの機能を活用し、HTMLテンプレート内で使用できる新しいカスタム関数を導入することで、ビルドステータスページの表示を改善しています。
ui.go
におけるカスタム関数の追加:template.FuncMap
にshortDesc
とshortUser
という2つの新しい関数が追加されました。これにより、これらの関数がHTMLテンプレートから直接呼び出せるようになります。shortDesc(desc string) string
:- この関数は、与えられた文字列
desc
(コミットのDescriptionを想定)の最初の改行文字(\n
)までの部分を返します。 - もし改行文字が含まれていなければ、元の文字列全体を返します。
- これにより、複数行にわたる長いコミットDescriptionを、テーブルの表示領域に収まるように1行に短縮して表示することが可能になります。
- この関数は、与えられた文字列
shortUser(user string) string
:- この関数は、与えられた文字列
user
(ユーザー名とメールアドレスを含む文字列、例: "Andrew Gerrand adg@golang.org")から、メールアドレス部分を抽出し、さらに@golang.org
の部分を除去してユーザーの短い識別子を返します。 - 具体的には、
<
と>
で囲まれた部分をメールアドレスとして抽出し、そのメールアドレスから@golang.org
というドメイン部分があればそれを取り除きます。 - これにより、冗長なメールアドレス全体ではなく、ユーザーの短いハンドル名のような形で表示できるようになります。
- この関数は、与えられた文字列
ui.html
における表示の改善:- カスタム関数の適用:
- ユーザー名表示:
{{.User}}
が{{shortUser .User}}
に変更され、shortUser
関数によってユーザー名が短縮されて表示されるようになりました。 - コミットDescription表示:
{{.Desc}}
が{{shortDesc .Desc}}
に変更され、shortDesc
関数によってDescriptionが1行に短縮されて表示されるようになりました。
- ユーザー名表示:
- タイムスタンプのフォーマット:
{{.Time.Time}}
が{{.Time.Time.Format "02 Jan 2006 15:04"}}
に変更されました。これにより、タイムスタンプが「日 月 年 時:分」という形式(例: "19 Dec 2011 16:57")で整形され、より人間が読みやすい形式になりました。
- CSSによるスタイリング:
.build .hash
と.build .time
というCSSセレクタに対してfont-family: monospace;
が追加されました。これにより、コミットハッシュとタイムスタンプが等幅フォントで表示されるようになり、視認性と整列が改善されました。
- カスタム関数の適用:
これらの変更により、ビルドステータスページはよりコンパクトで、重要な情報が強調され、全体的に読みやすいレイアウトに改善されました。
コアとなるコードの変更箇所
diff --git a/misc/dashboard/app/build/ui.go b/misc/dashboard/app/build/ui.go
index 918b53e5bd..1e7ea876b4 100644
--- a/misc/dashboard/app/build/ui.go
+++ b/misc/dashboard/app/build/ui.go
@@ -148,7 +148,9 @@ var uiTemplate = template.Must(\
template.New("ui").
Funcs(template.FuncMap{
"builderTitle": builderTitle,
+ "shortDesc": shortDesc,
"shortHash": shortHash,
+ "shortUser": shortUser,
"repoURL": repoURL,
}).
ParseFile("build/ui.html"),
@@ -159,7 +161,15 @@ func builderTitle(s string) string {
return strings.Replace(s, "-", " ", -1)
}\n
-// shortHash returns a the short version of a hash.\n+// shortDesc returns the first line of a description.\n+func shortDesc(desc string) string {\n+\tif i := strings.Index(desc, "\n"); i != -1 {\n+\t\tdesc = desc[:i]\n+\t}\n+\treturn desc\n+}\n+\n+// shortHash returns a short version of a hash.\n func shortHash(hash string) string {\n if len(hash) > 12 {\n hash = hash[:12]\n@@ -167,6 +177,17 @@ func shortHash(hash string) string {\n return hash\n }\n \n+// shortUser returns a shortened version of a user string.\n+func shortUser(user string) string {\n+\tif i, j := strings.Index(user, "<"), strings.Index(user, ">"); i != -1 && j > i {\n+\t\tuser = user[i+1 : j]\n+\t\tif k := strings.Index(user, "@golang.org"); k != -1 {\n+\t\t\tuser = user[:k]\n+\t\t}\n+\t}\n+\treturn user\n+}\n+\n // repoRe matches Google Code repositories and subrepositories (without paths).\n var repoRe = regexp.MustCompile(`^code\\.google\\.com/p/([a-z0-9\\-]+)(\\.[a-z0-9\\-]+)?$`)\n \ndiff --git a/misc/dashboard/app/build/ui.html b/misc/dashboard/app/build/ui.html
index 684ae1333f..80a924bfca 100644
--- a/misc/dashboard/app/build/ui.html
+++ b/misc/dashboard/app/build/ui.html
@@ -29,11 +29,15 @@\n .build tr:nth-child(2n) {\n background-color: #f0f0f0;\n }\n+ .build .hash {\n+ font-family: monospace;\n+ }\n .build .result {\n text-align: center;\n width: 50px;\n }\n .build .time {\n+ font-family: monospace;\n color: #666;\n }\n .build .descr, .build .time, .build .user {\n@@ -83,9 +87,9 @@\n {{end}}\n </td>\n {{end}}\n- <td class=\"user\">{{.User}}</td>\n- <td class=\"time\">{{.Time.Time}}</td>\n- <td class=\"desc\">{{.Desc}}</td>\n+ <td class=\"user\">{{shortUser .User}}</td>\n+ <td class=\"time\">{{.Time.Time.Format "02 Jan 2006 15:04"}}</td>\n+ <td class=\"desc\">{{shortDesc .Desc}}</td>\n </tr>\n {{end}}\n </table>\n```
## コアとなるコードの解説
### `misc/dashboard/app/build/ui.go`
1. **`template.FuncMap`への関数登録**:
```go
var uiTemplate = template.Must(
template.New("ui").
Funcs(template.FuncMap{
"builderTitle": builderTitle,
"shortDesc": shortDesc, // 新規追加
"shortHash": shortHash,
"shortUser": shortUser, // 新規追加
"repoURL": repoURL,
}).
ParseFile("build/ui.html"),
)
```
- `template.FuncMap`に`"shortDesc"`と`"shortUser"`というキーで、それぞれ`shortDesc`関数と`shortUser`関数が登録されています。これにより、`ui.html`テンプレート内で`{{shortDesc .Desc}}`や`{{shortUser .User}}`のようにこれらの関数を呼び出すことが可能になります。
2. **`shortDesc`関数の実装**:
```go
// shortDesc returns the first line of a description.
func shortDesc(desc string) string {
if i := strings.Index(desc, "\n"); i != -1 {
desc = desc[:i]
}
return desc
}
```
- `strings.Index(desc, "\n")`は、文字列`desc`内で最初の改行文字`\n`が出現するインデックスを検索します。
- もし改行文字が見つかった場合(`i != -1`)、`desc = desc[:i]`によって、文字列をその改行文字の直前まででスライス(切り詰め)します。
- これにより、複数行のDescriptionが1行に短縮されます。
3. **`shortUser`関数の実装**:
```go
// shortUser returns a shortened version of a user string.
func shortUser(user string) string {
if i, j := strings.Index(user, "<"), strings.Index(user, ">"); i != -1 && j > i {
user = user[i+1 : j] // "<" と ">" の間の文字列 (メールアドレス) を抽出
if k := strings.Index(user, "@golang.org"); k != -1 {
user = user[:k] // "@golang.org" があればその前までを抽出
}
}
return user
}
```
- `strings.Index(user, "<")`と`strings.Index(user, ">")`で、ユーザー文字列内の`<`と`>`のインデックスを検索します。
- もし両方が見つかり、`<`が`>`より前にある場合(`i != -1 && j > i`)、`user = user[i+1 : j]`によって、`<`と`>`の間の文字列(通常はメールアドレス)を抽出します。
- 抽出されたメールアドレスに`@golang.org`が含まれている場合(`k != -1`)、`user = user[:k]`によって、`@golang.org`の前の部分(ユーザー名)を抽出します。
- これにより、`Andrew Gerrand <adg@golang.org>`のような文字列から`adg`のような短いユーザー識別子が得られます。
### `misc/dashboard/app/build/ui.html`
1. **CSSスタイルの追加**:
```html
<style>
/* ... 既存のスタイル ... */
.build .hash {
font-family: monospace;
}
/* ... 既存のスタイル ... */
.build .time {
font-family: monospace;
color: #666;
}
/* ... 既存のスタイル ... */
</style>
```
- `.build .hash`と`.build .time`というクラスを持つ要素(それぞれコミットハッシュとタイムスタンプを表示する部分)に`font-family: monospace;`が適用されています。これにより、これらのテキストが等幅フォントで表示され、視認性が向上します。
2. **テンプレート内での関数呼び出しとフォーマット**:
```html
<td class="user">{{shortUser .User}}</td>
<td class="time">{{.Time.Time.Format "02 Jan 2006 15:04"}}</td>
<td class="desc">{{shortDesc .Desc}}</td>
```
- `<td class="user">`: ユーザー名を表示するセルで、`{{.User}}`が`{{shortUser .User}}`に変更され、Go側で定義された`shortUser`関数が呼び出されてユーザー名が短縮されます。
- `<td class="time">`: タイムスタンプを表示するセルで、`{{.Time.Time}}`が`{{.Time.Time.Format "02 Jan 2006 15:04"}}`に変更されています。これにより、`time.Time`オブジェクトの`Format`メソッドが呼び出され、指定されたレイアウト文字列(`"02 Jan 2006 15:04"`)に従ってタイムスタンプが整形されます。
- `<td class="desc">`: コミットDescriptionを表示するセルで、`{{.Desc}}`が`{{shortDesc .Desc}}`に変更され、Go側で定義された`shortDesc`関数が呼び出されてDescriptionが1行に短縮されます。
これらの変更により、ダッシュボードのビルドステータスページは、より整理され、情報が効率的に表示されるようになりました。
## 関連リンク
- Go CL 5493077: [https://golang.org/cl/5493077](https://golang.org/cl/5493077)
## 参考にした情報源リンク
- Go言語 `html/template` パッケージ: [https://pkg.go.dev/html/template](https://pkg.go.dev/html/template)
- Go言語 `time` パッケージ: [https://pkg.go.dev/time](https://pkg.go.dev/time)
- CSS `font-family` プロパティ (MDN Web Docs): [https://developer.mozilla.org/ja/docs/Web/CSS/font-family](https://developer.mozilla.org/ja/docs/Web/CSS/font-family)
- Go言語 `strings` パッケージ: [https://pkg.go.dev/strings](https://pkg.go.dev/strings)