株式会社クリアコード > ククログ

ククログ


github-post-receiverの複数サイト対応

はじめに

クリアコードでは最近Gitリポジトリの管理ツールをgitoliteからGitLabに移行*1しました。

クリアコードではgit-utilsを使用してdiff付きのコミットメールを配信しているのですが、GitLabに移行した当初はgithub-post-receiverがGitLab 6.0に対応しきれていませんでした。 github-post-receiverをGitLabで使用する場合は、以下の2つの制限がありました。

  • 同じリポジトリ名を異なるオーナー間で使用することができない
  • 複数サイト運用時にリポジトリ名を一意にしなければならない

この2つの制限の原因はgithub-post-receiverのGitLab対応が不十分であったことと複数サイトでの運用を考慮していなかったことでした。

そこで、この2つの制限を撤廃するための対応をしたのですが、一部互換性をなくす必要があったので、その説明と新しい設定ファイルの書き方の説明をします。

設定ファイルについて

github-post-receiverで複数サイトに対応するための設定ファイルの書き方を説明します。設定ファイルは後方互換性を維持しています。

github-post-receiverにはconfig.yamlという設定ファイルが必要です。 古い書式は以下の通りです。

to: receiver@example.com
error_to: admin@example.com
exception_notifier:
  subject_label: "[git-utils]" 
sender: sender@example.com
add_html: true
owners:
  ranguba:
    to: groonga-commit@rubyforge.org
    repositories:
      examples:
        to: null@example.com
  groonga:
    to: groonga-commit@lists.sourceforge.jp

1つのサイトからのpost-receive-hooksしか受け付けないのであれば、古い書式のままでも問題ありません。 これは、古い書式の場合は全てのサイトで同一の設定を使用するようになっているためです。

複数のサイト*2を運用している場合は以下のようにdomainsキーを追加した設定ファイルを書けば、複数サイト運用時にgithub.comとGHEでリポジトリ名が重複していてもそれぞれのサイトごとにコミットメールの宛先などを設定することができます。

to: global-to@example.com
error_to: error@example.com
exception_notifier:
  subject_label: "[git-utils]" 
sender: sender@example.com
add_html: false
domains:
  github.com:
    add_html: true
    owners:
      clear-code:
        to: commit@clear-code.com
      ranguba:
        to:
          - groonga-commit@rubyforge.org
          - commit@clear-code.com
        repositories:
          examples:
            to: null@example.com
      groonga:
        to: groonga-commit@lists.sourceforge.jp
  ghe.example.com:
    owners:
      clear-code:
        to:
          - commit@example.com
        from: null@example.com
        repositories:
          test-project1:
            to: commit+test-project1@example.com
          test-project2:
            to: commit+test-project2@example.com
      support:
        to: support@example.com
        from: null+support@example.com
  ghe.example.co.jp:
    add_html: true
    owners:
      clear-code:
        to:
          - commit@example.co.jp
        from: null@example.co.jp
        repositories:
          test-project1:
            to: commit+test-project1@example.co.jp
          test-project2:
            to: commit+test-project2@example.co.jp
      support:
        to: support@example.co.jp
        from: null+support@example.co.jp

設定は、一番狭い(深い)指定にマッチしたものを使用します。 いくつか具体的に説明します。

  • github.com/clear-code以下のリポジトリへのコミットはcommit@clear-code.comにコミットメールを送る
  • github.com/ranguba以下のリポジトリへのコミットはgroonga-commit@rubyforge.orgとcommit@clear-code.comにコミットメールを送る。ただしranguba/examplesリポジトリはnull@example.comにコミットメールを送る
  • github.com/milter-manager/milter-managerにpost-receive-hooksを設定した場合はglobal-to@example.comにコミットメールを送る
  • ghe.example.com/clear-code以下のリポジトリはtest-project1とtest-project2を除いてcommit@example.comにコミットメールを送る
  • ghe.example.co.jp/clear-code以下のリポジトリはtest-project1とtest-project2を除いてcommit@example.co.jpにコミットメールを送る

詳しくはテストコードを参照してください。

非互換について

以前のバージョンとの非互換を説明します。

github-post-receiverは、通知が来るとリポジトリをミラーリングします。このときにgithub-post-receiverが動作しているホスト上のディレクトリ構成を変更しました。 以下のようにリポジトリのURIからドメイン名も抽出してパスの一部として使うようになっています。 また、GitLabではowner_nameが"$gitlab"固定だったのをやめ、リポジトリのURIからowner_nameを抽出するようにしました。

Before: mirrors/#{owner_name}/#{repository_name}
After : mirrors/#{domain}/#{owner_name}/#{repository_name}

以前からgithub-post-receiverを使用している場合は、事前にミラーしたリポジトリを移動しておくと無駄なミラーリングを行いません。 パスが変わるだけなので、事前にミラーしたリポジトリを移動しなかった場合でもディスクを余分に使用すること以外に害はありません。

まとめ

git-utilsがGitLabのpost-receive-hooksと複数サイトの運用に対応したのでその説明をしました。 今後もより便利に使えるように、改善していきたいと考えているのでgit-utilsのissueに今後やりたいことをあげておきました。

お時間のある方は、取り組んでみるとよいかもしれません。

*1 GitLab 6.0のリリース後に移行しました

*2 例えばgithub.comと社内のGHE

2013-11-08

gettextとバージョン管理システムの相性の悪さを解消する案

gettextという翻訳の仕組み*1はフリーソフトウェアではよく使われています。いくつか不便な点はありますが、長年使われている仕組みでツールが揃っていることが理由でしょう。不便な点の1つである、「バージョン管理システムとの相性の悪さ」を解消する案が浮かんだので紹介します。

どうしてバージョン管理システムと相性が悪いか

gettextでは.poファイルに翻訳したテキストを書きます。翻訳したテキストは自動生成ではない情報なのでバージョン管理対象です。ということで、.poファイルはリポジトリーに入れます。

バージョン管理システムと相性が悪い原因は、.poファイルに翻訳したテキスト以外のいろいろな情報が入っていることです。中でも、「どこに翻訳対象のメッセージがあったか」は自動生成できる情報で、量も多く、通常であればバージョン管理しない情報です。しかし、バージョン管理したい.poファイルの中に含まれているので一緒にバージョン管理対象になってしまいます。これが相性が悪い点です。

ただ、「どこに翻訳対象のメッセージがあったか」は翻訳時には有用な情報なので単に.poファイルから消してしまうと翻訳時に不便です。翻訳時の利便を減らさずにこの相性の悪さを解決しようと試みるのがこの記事で説明する案です。

相性が悪い具体例

gettextとバージョン管理システムを一緒に使うと相性が悪いケースを具体的に確認しましょう。

まず、リポジトリーを用意します。

% mkdir -p /tmp/gettext-and-vcs
% cd /tmp/gettext-and-vcs
% git init

gettextを使ったプログラムを用意します。

hello.c:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <libintl.h>

int
main(void)
{
  puts(gettext("Hello"));
  return 0;
}

この中のgettext("Hello")の「Hello」がgettextで翻訳するメッセージです。

リポジトリーに追加します。

% git add hello.c
% git commit

次の作業の前に、gettextでどのように翻訳するかのざっくりとした流れを示します。

  1. 翻訳したい対象を用意する(今回の場合はhello.c)
  2. 翻訳したい対象から翻訳対象のメッセージを抽出する(今回の場合はHello)
  3. 抽出した翻訳対象のメッセージから.poファイルを作る
  4. .poファイルの中の翻訳対象のメッセージを翻訳する
  5. .poファイルから.moファイルを作る
  6. .moファイルにあるデータを使って翻訳対象のメッセージを翻訳する

今は1.の「翻訳したい対象を用意する」を用意した段階です。

それでは、2.の「翻訳したい対象から翻訳対象のメッセージを抽出する」をやってみましょう。xgettextというツールで抽出し、抽出したメッセージをpo/hello.potに出力します*2

% mkdir -p po/
% (cd po && xgettext --package-name Hello --package-version 1.0.0 --output hello.pot ../hello.c)
% cat po/hello.pot
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Hello 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-14 22:27+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: ../hello.c:7
msgid "Hello"
msgstr ""

最後の部分が大事なところです。

#: ../hello.c:7
msgid "Hello"
msgstr ""

hello.cの7行目の「Hello」を翻訳対象のメッセージとして抽出しました。

次に、3.の「抽出した翻訳対象のメッセージから.poファイルを作る」をやりましょう。

% msginit --locale ja_JP.UTF-8 --input po/hello.pot --output-file po/ja.po
... (メールアドレスを入力) ...
% cat po/ja.po
# Japanese translations for Hello package
# Hello パッケージに対する英訳.
# Copyright (C) 2013 THE Hello'S COPYRIGHT HOLDER
# This file is distributed under the same license as the Hello package.
# Kouhei Sutou <kou@clear-code.com>, 2013.
#
msgid ""
msgstr ""
"Project-Id-Version: Hello 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-14 22:27+0900\n"
"PO-Revision-Date: 2013-11-14 22:28+0900\n"
"Last-Translator: Kouhei Sutou <kou@clear-code.com>\n"
"Language-Team: Japanese\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#: ../hello.c:7
msgid "Hello"
msgstr ""

翻訳対象のメッセージの前にはメタデータがいろいろ入っています。2.でできた.potファイルはバージョン管理しませんが、ここで作った.poファイルはバージョン管理対象です。

% echo '*.pot' >> .gitignore
% git add .gitignore
% git add po/ja.po
% git commit

いよいよ翻訳です。4.の「.poファイルの中の翻訳対象のメッセージを翻訳する」になります。.poファイルを編集するためのエディターは、翻訳対象のメッセージがどのように使われているかをすぐに確認できる機能がある*3ので、それを使いながら翻訳します。このとき、翻訳対象のメッセージのすぐ上にある「../hello.c:7」という「どこに翻訳対象のメッセージがあったか」という情報を使います。本来であればバージョン管理対象としない情報ですが、翻訳時には便利なので.poファイルに入っている情報です。

% editor po/ja.po
% git diff
diff --git a/po/ja.po b/po/ja.po
index 0a90c72..49e9f76 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -9,7 +9,7 @@ msgstr ""
 "Project-Id-Version: Hello 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2013-11-14 22:27+0900\n"
-"PO-Revision-Date: 2013-11-14 22:28+0900\n"
+"PO-Revision-Date: 2013-11-14 22:34+0900\n"
 "Last-Translator: Kouhei Sutou <kou@clear-code.com>\n"
 "Language-Team: Japanese\n"
 "Language: ja\n"
@@ -20,4 +20,4 @@ msgstr ""

 #: ../hello.c:7
 msgid "Hello"
-msgstr ""
+msgstr "こんにちは"

この変更*4はバージョン管理対象です。せっかくの翻訳を失いたくありません。

% git add po/ja.po
% git commit

ここからは翻訳したメッセージを使うための作業です。

まず、.moファイルを作ります。5.の「.poファイルから.moファイルを作る」という作業です。.moファイルは.poファイルをコンパイルした実行に都合のよいファイルだと理解すれば十分です。locale/ja/LC_MESSAGES/hello.moに置きます*5

% mkdir -p locale/ja/LC_MESSAGES/
% msgfmt --output-file locale/ja/LC_MESSAGES/hello.mo po/ja.po

なお、.moファイルは.poファイルから自動生成できるためバージョン管理対象外です。

% echo /locale/ >> .gitignore
% git add .gitignore
% git commit

いよいよ翻訳したメッセージを使います。6.の「.moファイルにあるデータを使って翻訳対象のメッセージを翻訳する」です。

% cc -o hello hello.c
% LANG=ja_JP.UTF-8 ./hello
Hello

あれ、英語のままですね。実は、元のプログラムは必要な関数呼び出しが足りません。

% editor hello.c
% git diff
diff --git a/hello.c b/hello.c
index b210f06..9852314 100644
--- a/hello.c
+++ b/hello.c
@@ -1,9 +1,13 @@
 #include <stdio.h>
 #include <libintl.h>
+#include <locale.h>

 int
 main(void)
 {
+  setlocale(LC_ALL, "");
+  bindtextdomain("hello", "locale");
+  textdomain("hello");
   puts(gettext("Hello"));
   return 0;
 }

実行してみましょう。

% cc -o hello hello.c
% LANG=ja_JP.UTF-8 ./hello
こんにちは

翻訳できたのでコミットします。

% git add hello.c
% git commit

実行ファイル「hello」は自動生成のファイルなので無視しておきましょう。

% echo /hello >> .gitignore
% git add .gitignore
% git commit

それではもうひとつメッセージを追加しましょう。

% git diff
diff --git a/hello.c b/hello.c
index 9852314..862f1df 100644
--- a/hello.c
+++ b/hello.c
@@ -9,5 +9,6 @@ main(void)
   bindtextdomain("hello", "locale");
   textdomain("hello");
   puts(gettext("Hello"));
+  puts(gettext("World"));
   return 0;
 }
% cc -o hello hello.c
% LANG=ja_JP.UTF-8 ./hello
こんにちは
World

追加した方はまだ翻訳されていませんが、プログラムは動いているのでコミットしましょう。

% git add hello.c
% git commit

それでは翻訳しましょう。

まず、.poファイルを更新します。

% (cd po && xgettext --package-name Hello --package-version 1.0.0 --output hello.pot ../hello.c)
% msgmerge --update po/ja.po po/hello.pot
... 完了.
% git diff | cat
diff --git a/po/ja.po b/po/ja.po
index 49e9f76..af14c60 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Hello 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-11-14 22:27+0900\n"
+"POT-Creation-Date: 2013-11-14 23:10+0900\n"
 "PO-Revision-Date: 2013-11-14 22:34+0900\n"
 "Last-Translator: Kouhei Sutou <kou@clear-code.com>\n"
 "Language-Team: Japanese\n"
@@ -18,6 +18,10 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"

-#: ../hello.c:7
+#: ../hello.c:11
 msgid "Hello"
 msgstr "こんにちは"
+
+#: ../hello.c:12
+msgid "World"
+msgstr ""

はい、注目!「World」用のエントリーが追加されただけではなく、「Hello」の出現位置情報(「../hello.c:7」)も更新されています。今はメッセージ数が少ないのであまり気になりませんが、通常はメッセージ数は数十や数百などもっと多くなります。そうすると出現位置の変更が数十や数百以上になります。例えば、Groongaのドキュメントで.poファイルを更新すると変更業は2000行くらいになります。メッセージを変更するたびにこのくらいの変更をバージョン管理するのはどうなんだろうと思うようになります。

バージョン管理システムとの相性の悪さを解消する案

ようやく本題です。バージョン管理システムとの相性の悪さを解消する案を紹介します。

まず状況を整理します。

  • .poファイルには出現位置情報があった方が翻訳時には便利
    • 翻訳時に簡単に出現位置を確認して、どのように翻訳するのが適切かを確認できるため
  • 出現位置情報は自動生成できる情報なので本来であればバージョン管理する必要はない
    • .poファイルにバージョン管理すべき情報もあるため出現位置情報もバージョン管理しないといけない

この状況を解決する案を思いつくヒントになったのがgrosser/gettext_i18n_rails#103でのやりとりです。このやりとりで.poファイルに出現位置情報を含めないという使い方をしている人がいることを知りました。

このヒントから、バージョン管理する.poファイルには出現位置情報を含めず、バージョン管理しない作業用の.poファイルを導入する案を思いつきました。作業用の.poファイルには出現位置情報を含めます。そのため、この.poファイルを使えば翻訳時の利便は失われません。作業用の.poファイルの名前をja.edit.poとすると以下のような使い分けです。

  • po/ja.po ← バージョン管理する。出現位置情報なし。
  • po/ja.edit.po ← バージョン管理しない。出現位置情報あり。

これを実現するためには以下のような作業の流れにします。

% msgmerge --output po/ja.edit.po po/ja.po po/hello.pot
... 完了.
% editor po/ja.edit.po # ← 出現位置情報付きなので今まで通りの利便性で翻訳できる
% msgcat --no-location --output po/ja.po po/ja.edit.po
% git diff
diff --git a/po/ja.po b/po/ja.po
index 49e9f76..81b1127 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Hello 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-11-14 22:27+0900\n"
-"PO-Revision-Date: 2013-11-14 22:34+0900\n"
+"POT-Creation-Date: 2013-11-14 23:10+0900\n"
+"PO-Revision-Date: 2013-11-14 23:34+0900\n"
 "Last-Translator: Kouhei Sutou <kou@clear-code.com>\n"
 "Language-Team: Japanese\n"
 "Language: ja\n"
@@ -18,6 +18,8 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"

-#: ../hello.c:7
 msgid "Hello"
 msgstr "こんにちは"
+
+msgid "World"
+msgstr "世界"

出現位置情報がなくなったので大量の不必要な変更行をバージョン管理しなくてもよくなりました。作業用の.poファイルはバージョン管理対象外にしてコミットしましょう。

% echo '*.edit.po' >> .gitignore
% git add .gitignore
% git commit
% git add po/ja.po
% git commit

作業用の.poファイルとバージョン管理用の.poファイルを作る手間が増えるというデメリットはありますが、これは自動化できるので気にならないのではないかと予想しています。

ただ、翻訳中に「バージョン管理システムの機能を使ってdiffを見る」ことがしづらくなるデメリットが解消できるか微妙なところです。実際にやってみないとなんとも言えません。

まとめ

gettextとバージョン管理システムは以下のように相性が悪いことを具体例と共に示しました。

  • 翻訳時には.poファイルに翻訳対象メッセージの出現位置情報が入っていると便利
  • 本来は出現位置情報はバージョン管理する必要はない
  • バージョン管理対象の.poファイルに出現位置情報が含まれているため、出現位置情報もバージョン管理せざるを得ない
  • 出現位置情報もバージョン管理するとノイズが大きい

これを解決する以下の案を紹介しました。

  • バージョン管理しない作業用の.poファイルを導入する
  • 作業用の.poファイルには出現位置情報を入れるため翻訳時の利便性は維持
  • 作業用の.poファイルから出現位置情報を抜いた.poファイルを作り、それをバージョン管理対象とする

この案により、gettextとバージョン管理システムの相性問題は解決しますが、もしかしたら、作業時に別の不便なことが発生するかもしれません。そのため、実際にこの案を試してみてよさそうかどうかを確認する必要があります。gettext gemにこの案の実践を支援する機能を入れたいところです。

なお、ここで作成したリポジトリーはGitHubにあります。コミットメッセージの書き方意図が伝わるコミットのしかたに興味のある人はのぞいてみてください。ライセンスはCC0(パブリックドメイン)です。

*1 gettextという仕組みの1つの実装がGNU gettextです。この記事では「gettext」を実装ではなく仕組みのことを指すために使います。

*2 cdしてからxgettextを実行しているのは、hello.cへのパスをこれから作る.poファイルからの相対パスにするためです。こうすると翻訳時にツールの助けを得られます。

*3 Emacs用の.poファイル編集モードであるpo-modeは「s」(たぶん、sourceからの連想)でメッセージの使用箇所を表示します。

*4 「PO-Revision-Date」の値はpo-modeが自動的に更新します。

*5 置き場所のルールがありますが、この記事の本質とは関係ないため省略します。

2013-11-14

Rubyで変数宣言っぽいものをした方が読みやすくなるとき

RubyはCのように変数宣言のための特別な構文はなく、変数に代入する式を書くとそれ以降その変数を使えるようになります。

1
2
3
1 + 1             # <- ここでは「message」変数を使えない
message = "Hello" # <- ここから「message」変数を使える
puts(message)     # <- ここでは「message」変数を使える

そのため、明示的に変数を宣言しようとすることはほとんどありません。そのように書かれているRubyのコードを見ると違和感を覚えるほどです。何か特別な意図があるのではないかと考えてしまいます。

1
2
3
4
5
message = nil # <- 変数を宣言するための代入式

1 + 1
message = "Hello"
puts(message)

しかし、このように変数を宣言するために代入式を使った方が読みやすくなる場合があります。どういう場合かを例と理由をつけて説明します。なお、どうしてこのようなことを書く気になったのかというと、コミットへのコメントサービスを実施したときのコメントのやりとりで話題になり、「こういう考えでやっている」ということを説明したからです*1

なお、スコープを広げるためには変数宣言をする「必要」がありますが、今回は、どういうときに必要かという話はしません。こういうときに使うのが「オススメ」という話だけします。

デフォルト値を設定するケース

「オススメ」のケースはデフォルト値を設定するケースです。このケースでは変数宣言のように最初に変数を初期化する必要はありません。しかし、次のように初期化した方が読みやすくなります。これは、一見、変数宣言のように見えますが、そうではなく、単にnilを設定しているだけです。

1
2
3
4
variable = nil
# ...variableを設定するかもしれない処理...
variable ||= default_value
variable

この書き方をしない場合はifを使って書いたりします。

1
2
3
4
5
6
7
if condition1
  variable = get_value1
elsif condition2
  variable = get_value2
else
  variable = default_value
end

単純な場合はこれでもよいのですが、次のように値を取得しようとしても失敗するかもしれない、という場合はデフォルト値の設定箇所が複数になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if condition1
  variable = get_value_if_success
  p variable # => nilかもしれない
  if variable.nil?
    variable = default_value # デフォルト値の設定箇所1
  end
elsif condition2
  variable = get_value_from_network
  p variable # => nilかもしれない
  if variable.nil?
    variable = default_value # デフォルト値の設定箇所2
  end
else
  variable = default_value # デフォルト値の設定箇所3
end

こうなると複雑なので次のような形にする方がオススメです。

1
2
3
4
5
6
7
8
variable = nil
if condition1
  variable = get_value_if_success
elsif condition2
  variable = get_value_from_network
end
variable ||= default_value # デフォルト値の設定
variable

この形では「デフォルト値の設定」という処理を1回だけ書けば済むようになっているのがよいところです。また、その処理をifの中ではなく必ず通るところに書いているおかげで「あぁ、この処理の塊では必ずデフォルト値を設定するんだな」感がでるのもよいところです。

ifでがんばる場合だと「抜けはないよね?抜けがあったとしたらそれは意図的なもので問題ないんだよね?」というのが気になります。

まとめ

変数宣言をする必要のないRubyでも、変数宣言っぽいことをした方が読みやすくなるケースがあります。それは「デフォルト値を設定するケース」です。

ちょっとしたことでも、読みやすくしたり、意図を伝えやすく書けたりするものです。この話を書くきっかけになったのは、Rubyをよく知らない人がRubyのコードのコミットを見て「Rubyはよく知らないんだけど、変数宣言はいらないのに変数宣言っぽいことをしているのはなんで?」とコメントしたことでした。このような何気ない疑問からちょっとした工夫が明文化され、開発チームの資産になったりします。

間違ったところを指摘するためだけに他の人のコードをチェックするのではなく、コミットを見て、気になったことを気軽にコメントできる文化を作ってみてはいかがでしょうか。今まで気づいていなかった自分たちのよいところに気づけるかもしれませんよ。

参考:

  • リーダブルコードの解説:「よいコードを書くことが当たり前」にしようよ、(中略)、そのためにはみんながみんなのコードを読む文化になっていないとね、(中略)、みたいな話
  • コミットへのコメントサービス:「みんながみんなのコードを読む文化」を作ることを支援するサービス*2

*1 今、そのコメントを見なおしてみると、このやりとりは2013/5/13にあったので、書こう思い立ってから半年も経っていたのですね。。。

*2 コミットへコメントすることがメインではないので、もっとよいしっくりくるサービス名がありそうだけど。。。

2013-11-21

«前月 最新記事 翌月»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|