Perforceのスクリプト: トリガとデーモン

Perforceの主要なスクリプトとしては、以下の2種類があります。

  • Perforceトリガは、ユーザが記述するプログラムまたはスクリプトです。これは、特定の操作(チェンジリストのサブミット、フォームに対する変更、ユーザによるログイン試行、パスワードの変更など)が実行されるたびに、Perforceサーバによって呼びされます。スクリプトが0の値を返す場合、操作を続行します。スクリプトが他の値を返す場合、操作を失敗させます。

  • デーモンは、前もって指定された時間に実行され、Perforceメタデータに対する変更を検索します。デーモンが、ディポの状態が何らかの指定された状態に変更されたと判断すると、他のコマンドを実行します。例えば、デーモンは、新しくサブミットされたチェンジリストを検索し、それらのファイルに対する変更の追跡に関心のあるユーザへ電子メールを送信します。Perforceで提供している各種のツールを使用すると、デーモンのスクリプトを容易に記述できます。

トリガ

トリガを使用すると、Perforceの機能を拡張またはカスタマイズすることができます。よく使用されるのは以下のような場合です。

  • Perforceプロテクションテーブルによって提供されるメカニズムの範囲を超えてチェンジリストの内容を検証する場合。例えば、サブミット前のトリガを使用することにより、チェンジリスト内のfile1がサブミットされるたびに、file2もサブミットされるようにすることができます。

  • 特定のPerforceコマンドの実行前または後に何らかのアクションを実行する場合。

  • フォームを検証する場合や、Perforceフォームのカスタマイズされたバージョンを提供する場合。例えば、フォームトリガを使用すると、ユーザがp4 clientコマンドを実行するときにカスタマイズされた既定のワークスペースビューを生成したり、適切なワークスペース説明をどんな場合でも入力させたりすることができます。

  • LDAPやActive Directoryなどの外部認証メカニズムと連動するようにPerforceを構成する場合。

    LDAP仕様の採用により、LDAP認証を有効化することが望ましい場合があります。詳細については、『Perforceの管理: スーパーユーザのタスク』の章の「認証オプション」のセクションを参照してください。

  • Perforceリポジトリの外部にアーカイブされたデータソースから内容を取得する場合。

説明を簡潔に行うために、このガイドでは、トリガスクリプトおよびトリガプログラムをトリガと呼びます。

トリガを作成し、Perforceに実行させるには、以下の操作を行う必要があります。

  1. プログラムまたはスクリプトを記述します。トリガの記述には、Perl、Python、Rubyなどのシェルスクリプトか、あるいはPerforceと相互運用できるあらゆるプログラミング言語を使用することができます。後者には、UNIXシェルやコンパイル型言語(C/C+など)が含まれます。

    トリガはトリガ変数にアクセスすることができます。この変数を使用すると、サーバ状態の情報、実行コンテキスト、クライアント情報、トリガに渡されたパラメータに関する情報などを取得することができます。トリガ変数に関する詳細については、トリガスクリプト変数を参照してください。

    トリガは、トリガ変数を使用するか、もしくは、STDINおよびSTDOUTを介してアクセスされるキー/値のペアのディクショナリを使用することにより、サーバと通信します。これらの方法の詳細については、トリガとサーバ間の通信を参照してください。

    トリガ変数によってアクセスできないデータが必要な場合には、トリガでコマンドラインクライアント(p4.exe)や、PerforceスクリプトAPI(P4-Ruby、P4-Python、P4-PHP)も使用することができます。詳細については、スクリプト用Perforce APIを参照してください。

    トリガは、サーバのファイルシステム上か、ディポそれ自体のなかに設置することができます。トリガをディポの中に置いて使用する方法について、詳しくはディポからトリガを実行するを参照してください。

    複数のサーバ全体に対するポータビリティをトリガにもたせる記述方法があります。詳細については、複数のPerforceサーバをサポートするトリガを作成するを参照してください。

  2. トリガ起動のタイミングを決定するトリガ定義を作成するには、p4 triggersコマンドを使用します。トリガ定義は4つのフィールドによって構成されます。これらのフィールドでは、トリガ名、発生すべきイベントのタイプ、トリガの場所に加えて、場合によっては、トリガの起動要件となる一致すべき数種のファイルパターンを指定します。

    詳細については、トリガ定義を参照してください。

Warning

トリガスクリプトを使用する際には、ディポにデータを書き込むPerforceコマンドは危険であり使用するべきではないことに留意してください。特に、トリガスクリプト内部からp4 submitコマンドを実行しないでください。

サンプルのトリガ

以下のコードサンプルは、bashauth-checkタイプのトリガです。このトリガは、Active Directoryを使用して、ユーザを(%user%変数でスクリプトに渡すことによって)認証することを試みます。失敗した場合、すべてのユーザに与えられている秘密のパスワード"secret"と一致するか比較します。また、特別なユーザ"bruno"には、パスワードなしでの認証を許可します。

USERNAME=$1
echo "USERNAME is $USERNAME"

# read user-supplied password from stdin
read USERPASS
echo Trying AD authentication for $USERNAME
echo $USERPASS | /home/perforce/p4auth_ad 192.168.100.80 389 DC=ad,DC=foo,DC=com $USERNAME
if [ $? == 0 ]
then
     # Successful AD
     echo Active Directory login successful
     exit 0
fi
# Compare user-supplied password with correct password, "secret"
PASSWORD=secret
if [ "$USERPASS" = $PASSWORD ]
then
     # Success
    exit 0
fi
if [ "$USERNAME" = "bruno" ]
then
    # Always let user bruno in
    exit 0
fi
# Failure
# password $USERPASS for $USERNAME is incorrect;
exit 1

このトリガを定義するには、p4 triggersコマンドを使用し、トリガフォームに以下のような1行を追加します。

bypassad auth-check auth "/home/perforce/bypassad.sh %user%"

これにより、ユーザがp4 loginコマンドを実行すると、auth-checkトリガが(存在する場合)起動します。パスワードは認証トリガに対してSTDINで送られます。

トリガの基本

このセクションでは、トリガおよびトリガ定義の記法に関する基本について解説します。それぞれのタイプのトリガの実装方法については、以下の各セクションを参照してください。このセクションでは、すべてのタイプのトリガに関する情報を提供します。

  • トリガ定義では、トリガテーブルのエントリフォームの基本について確認します。

  • 実行環境では、使用中のスクリプトがその実行環境に関する適正な情報を含んでいるかどうか確認する方法について説明します。

  • ディポからトリガを実行するでは、ディポからトリガを実行する場合にディポパスを構成する方法について説明します。

  • トリガとサーバ間の通信では、通信に使用するメソッドの選択方法と、ディクショナリ入力の解析方法について解説します。

  • 複数のトリガを使用するでは、トリガテーブルが複数のトリガ定義を含んでいる場合、それがPerforceによってどのように解釈および処理されるかということについて説明します。

  • 複数のPerforceサーバをサポートするトリガを作成するでは、ひとつのトリガを複数のPerforceサーバ間で移植しやすくする方法について説明します。

  • トリガと分散アーキテクチャでは、トリガをレプリカに置く場合に注意を要する諸問題について説明しています。

トリガのデバッグについて詳しくは、http://answers.perforce.com/articles/KB/1249を参照してください。

トリガ定義

トリガを記述したら、p4 triggersコマンドを発行し、トリガフォーム内にトリガの情報を提供することにより、トリガ定義を作成します。(Perforceスーパーユーザでなければこのコマンドを使用できません。)p4 triggersフォームは以下のように表示されます。

Triggers:
  relnotecheck change-submit //depot/bld/...  "/usr/bin/rcheck.pl %user%"
  verify_jobs  change-submit //depot/...      "/usr/bin/job.py %change%"

フォームを使用するすべてのPerforceコマンドと同様に、フィールド名(Triggers:など)を左揃えとし、その末尾に":"を使用する必要があります。また、フィールド値(つまり追加する行の集合のこと。それぞれが各トリガに対応)は、フィールド名の下の行ではスペースまたはタブによってインデントされている必要があります。

p4 Triggersコマンドの使用時に入力するトリガフォーム中の各行には、4つのフィールドがあります。これらのフィールドについて、以下の表で簡単に説明します。これらのうち3つのフィールドで使用する値はトリガタイプによって異なります。こうした値については、各トリガタイプの解説を行うセクションで、あらためて詳しく説明します。nameフィールドでは、すべてのトリガタイプに対して同じ形式が使用されます。

フィールド

意味

name

ユーザによって定義されるトリガ名です。

複数のファイルパターンに同じトリガスクリプトを使用するには、トリガテーブル中の隣接する複数の行に、同じトリガを複数回記入します。排他的マッピングを使用して、ファイルにトリガスクリプトが実行されないようにします。トリガエントリーの順序は、まさしく排他的マッピングがビューで使用される場合に重要です。この場合、そうした最初のトリガ行のうちcommandのみが使用されます。

type

トリガは8つのカテゴリーに分類されます。すなわち、サブミットトリガ、コマンドトリガ、保留トリガ、エッジサーバトリガ、修正トリガ、フォームトリガ、認証トリガ、アーカイブトリガです。これらのカテゴリごとに1つ以上のトリガタイプが定義されています。例えば、サブミットトリガには、change-submitchange-contentchange-commitchange-failedの各タイプが含まれます。

各タイプと各トリガの関連づけの判断については、関連のカテゴリーについて説明しているセクションを参照してください。

path

このフィールドの用法は、トリガタイプによって異なります。例えば、サブミットトリガ、エッジサーバトリガ、保留トリガの場合、このフィールドはディポシンタックスのファイルパターンです。ユーザがこのパターンに一致するファイルを含むチェンジリストをサブミットすると、トリガスクリプトが実行されます。

そのトリガに適切なパスを選択するには、関連のトリガについて説明しているセクションを参照してください。

command

このPerforceサーバ向けトリガは、トリガ定義によって暗黙的に指定された条件が満たされると実行されます。

たとえサーバがUnicodeモードで稼働しており、トリガスクリプトに変数をUTF8で渡す場合であっても、トリガスクリプト名または実行ファイル名はASCIIで指定する必要があります。

Perforceサーバがコマンドの参照場所を特定して実行できるような形で、トリガを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

オペレーティングシステムがトリガを実行ファイルとして認識しないようなプラットフォームでは、インタープリタをコマンドフィールドで指定する必要があります。例えば、Windowsは.plファイルを実行ファイルとして認識しません。

lo form-out label  "perl //myscripts/validate.pl"

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl //depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

トリガは、トリガテーブルに記載された順序で実行されます。あるトリガスクリプトが特定のタイプに関して正常に実行されなかった場合、そのタイプに関連づけられた後続のスクリプトも実行されません。

p4 triggersコマンドの構文はきわめて単純です。

p4 triggers [ -i | -o ]

  • フラグを指定しない場合、ユーザのエディタが起動し、トリガ定義の指定を要求されます。

  • -iフラグは、標準入力からトリガテーブルを読み取ります。

  • -oフラグは、トリガテーブルに保存されたトリガ定義を表示します。

実行環境

トリガのテストおよびデバッグ時には、スクリプト内から呼び出されたすべてのp4コマンドは、呼び出しているユーザの環境とは異なる環境(P4USERP4CLIENTなど)の内部で実行されるということについて留意してください。したがって、トリガスクリプトの内部から必要な環境を初期化するように注意し、現在の環境からこれらの値を使い回すことがないようにしてください。例:

export P4USER=george
export P4PASSWD=abracadabra
cd /home/pforce/database

p4 admin checkpoint
ls -l checkpoint.* journal*

基本的に、以下のガイドラインを順守することを推奨します。

  • 可能な限り、実行ファイルにはフルパスを使用してください。

  • スペースを含むパス名については、ショートパス名を使用してください。

    例えば、C:\Program Files\Perforce\p4.exeの位置はC:\PROGRA~1\Perforce\p4.exeである可能性が高いです。

  • ログインチケットをテスト段階と同じ場所に置くことはできません。テストの場合なら、p4 login < input.txtを使用してデータ内に渡すことができます。

  • トラブルシューティングのために、出力のログをファイルに記録してください。例:

    date /t >> trigger.log
    p4 info >> trigger.log
    C:\PROGRA~1\Perforce\p4.exe -p myServer:1666 info
    

    trigger.logがまったく更新されない場合、トリガが起動していなかったことを意味します。第1のp4 infoが失敗し、第2のp4 infoが正常に実行された場合、環境設定に異なる点があったかどうかが判明します。

  • トリガスクリプト中のPerforceコマンドは、常に、ある特定のPerforceユーザによって実行されます。ユーザが指定されていない場合、SYSTEMというユーザ(あるいはUNIX上ではp4dプロセスの所有権を持つユーザ)がPerforce臨時ライセンスを使用していると見なされます。これが起きるのを防ぐには、以下の操作を行います。

    • トリガがPerforceコマンドを呼び出すたびに、%user%引数をそのトリガに渡すことによって、そのコマンドが確実に該当ユーザによって実行されるようにします。例えば、ジョーがトリガスクリプトtrigger.plをアクティベートするチェンジリストをサブミットし、trigger.plp4 changesコマンドを呼び出している場合、そのスクリプトで実行するコマンドをp4 -u %user% changesなどとすればよいでしょう。

    • P4USERに、トリガを実行するアカウントとして既存のユーザ名を指定します。(PerforceサーバがWindows環境下でサービスとしてインストールされている場合、WindowsサービスではP4USERの値が使用できないことに注意してください。Windows上では、上で説明したようにユーザの値を各コマンドに渡す必要があります。)

  • 既定では、Perforceサービスは、WindowsローカルSystemアカウントのもとで動作します。Systemアカウントは、テストもしくはトリガの記述に使用している環境構成とは異なる環境構成(Perforce関連の変数ばかりではなくPATH設定およびファイルパーミッションまでをも含む)を持っている可能性があります。

  • Windowsでネットワークドライブ上のファイルにアクセスするにはリアルアカウント名とパスワードが必要であるため、トリガスクリプトがネットワークドライブ上に存在する場合、そのスクリプトにアクセスするにはサービス構成によってリアルユーザIDとパスワードを使用する必要があります。

  • Windows上では、既定の標準入力はバイナリモードではありません。テキストモードでは行末の変換は標準入力で実行されますが、それはバイナリファイルにとっては不適当です。

    Windowsマシン上でバイナリファイルに対してアーカイブトリガを使用している場合、標準入力を確実にバイナリモードに切り替えることにより、意図しない行末の変換を必ず防いでください(O_BINARY)。

ディポからトリガを実行する

ディポに置かれているトリガを実行することができます。これを実行するには、トリガ定義のコマンドフィールドで、トリガを含むプレーンディポファイルまたはストリームディポファイルのパス名を(任意でリビジョン番号と合わせて)指定し、パーセント記号で囲みます。追加の変数をトリガに渡す必要がある場合、通常どおりそれらをコマンドフィールドに追加します。サーバが一時ファイルを作成します。そこには、コマンドフィールドに指定したファイルパス名の内容が記録されます。(一時ファイルの使用が望ましい理由は、まずそれがセキュリティ上必要だからであり、またディポファイルは通常いくらか処理を経てからでなければ実行できないからです。)

トリガとして使用するディポファイルは、すでに存在しているものでなければなりません。内容が使用可能であれば、あらゆるファイルタイプが許容されます。Unicode対応のサーバ上では、一時ファイルはUTF-8のテキストタイプになります。ディポスクリプトファイルの内容は、信頼されているユーザのみが読み書きできるように保護しておく必要があります。

ファイルパス名にスペースが含まれる場合や、追加のパラメータを渡す必要がある場合は、コマンドフィールドを引用符で囲む必要があります。

次のトリガ定義では、インタープリタがトリガのために指定されています。オペレーティングシステムがトリガの実行方法を認識しないようなプラットフォームでは、インタープリタを指定する必要があります。例えば、Windowsでは.plファイルが実行ファイルとして認識されません。

lo form-out label  "perl %//admin/validate.pl%"

次のトリガ定義では、ディポパスがリビジョン番号を含んでいるため引用符で囲まれています。インタープリタ値が指定されていない場合、オペレーティングシステムがスクリプトを直接実行できるということを意味します。

lo form-out branch "%//depot/scripts/validate#123.exe%"

Warning

ディポファイルパス名に予約文字を含めることはできません。なぜなら、16進数変換後の予約文字には、%var%の区切り文字として使用されているパーセント記号が含まれるからです。例えば、@myScriptというファイル名は使用できません。なぜなら、%40myScriptに変換されるため、これをvarに代入すると%%40myScript%となってしまうからです。

トリガとサーバ間の通信

トリガは、2つの方法のうちいずれか1つでサーバと通信します。すなわち、トリガスクリプト変数で説明している変数を使用するか、もしくはSTDINおよびSTDOUTを介してキー/値のペアのディクショナリーを使用します。triggers.ioコンフィギュレーション変数の設定しだいで、どちらかの方法が使用されます。またどちらの方法が選択されたかによって、STDINおよびSTDOUTの内容や、トリガ失敗の処理方法が異なります。以下の表では、これらの設定による結果を要約しています。クライアントは、トリガを実行するサーバに接続されているクライアントアプリケーション(Swarm、P4V、P4Winなど)を指します。

 

triggers.io = 0

triggers.io = 1

トリガ成功

トリガはサーバとの通信にトリガ変数を使用します。

STDINを使用するのはアーカイブトリガまたは認証トリガに限られます。アーカイブトリガではSTDINはファイルコンテンツに使用され、認証トリガではSTDINはパスワードに使用されます。

アーカイブトリガを除くすべてのトリガのSTDOUTは、未修飾のメッセージとしてクライアントに送信されます。アーカイブトリガの場合、コマンドの標準出力はファイルコンテンツです。

トリガは0の値で終了する必要があります。

トリガはサーバとの通信にSTDINおよびSTDOUTを使用します。

STDINは、%clienthost%および%peerhost%を除くすべてのトリガ変数の名前と値のペアから成るテキストディクショナリーです。

この設定は、アーカイブトリガまたは認証トリガに関しては、STDINの値に影響を及ぼしません。

トリガは0の値で終了する必要があります。

トリガ失敗

トリガのSTDOUTおよびSTDERRは、トリガ失敗エラーメッセージの文字列として、クライアントに送信されます。

トリガは0以外の値で終了する必要があります。

STDOUTはエラー情報を含むテキストディクショナリーです。STDERRはSTDOUTとマージされます。

トリガ失敗ということは、すなわち、トリガスクリプトが実行できない、出力ディクショナリーに失敗メッセージが含まれている、出力の形式が不適切であるということです。実行エラーはサーバによって記録され、サーバはSTDOUTによって指定された情報をクライアントに送信します。ディクショナリーが提供されていない場合、サーバは、何らかの問題が発生したことを示す一般的なメッセージをクライアントに送信します。

ディクショナリーの形式は、キー/値のペアから成る複数の行の連続です。印字不能文字は、パーセントエンコーディングで符号化される必要があります。データは、Unicode対応サーバ上では、UTF-8でエンコードされているものとして扱われます。%dictionaryにおける%client%、%clientprog%、%command%、%user%変数の記述例を以下に列挙します。

client:jgibson-aaaatchoooo
clientprog:P4/LINUX45X86_128/2017.9.MAIN/1773263782 (2017/OCT/09).
command:user-dwim
user:jgibson

上記の例では、ディクショナリーの一部のみを示しています。このようにして変数が渡される場合、トリガスクリプト変数で説明しているすべての変数はSTDINに渡されます。たとえスクリプトがこれらの変数の一部しか参照しないとしても、トリガスクリプトはSTDINのすべてを読み取る必要があります。スクリプトがSTDINのすべてを読み取らない場合、スクリプトは失敗し、サーバで以下のようなエラーが記録されます。

write: yourTriggerScript: Broken pipe

トリガはSTDOUTを介してディクショナリーをサーバに送り返す必要があります。ディクショナリーには、少なくとも1つのアクションが含まれている必要があります(アクションは任意で1つのメッセージを伴うことが可能です)。アクションはpassまたはfailのいずれかです。印字不能文字は、パーセントエンコーディングで符号化される必要があります。例:

action:fail
message:too bad!

欠陥のあるトリガがディクショナリーに応答し、実行時に発生した問題が一般的なエラーとともにクライアントに報告されます。詳細なメッセージはサーバログに記録されます。

このセクションの冒頭で示唆したように、サーバとの通信に使用される2つの方法は互いに排他的な関係にあります。両者は概して両立しません。ただし、1つだけ例外があり、その場合にはたとえtriggers.ioを1に設定していたとしても、コマンドラインで変数を指定する必要があります。この例外とは、%peerhost%変数または%clienthost%変数を参照する意図がある場合です。こうした変数を渡すことは非常に非効率的です。ディクショナリーに含まれるべきそれらの値については、コマンドライン上で1つまたは両方を指定する必要があります。

以下のサンプルは、入力ディクショナリーをユーザにエコーするPerlプログラムです。

use strict;
use warnings FATAL=>"all";
use open qw/ :std :utf8 /;
use Data::Dumper;
use URI::Escape;

$Data::Dumper::Quotekeys = 0;
$Data::Dumper::Sortkeys  = 1;

my %keys = map { /(.*):(.*)/ } <STDIN>;

print "action:pass\nmessage:" . uri_escape Dumper \ %keys;

ソースリストの冒頭では、いくつかのコードによって基本のUnicodeサポートのためにPerlを設定し、さらに少々のエラー処理を加えています。プログラムの核心は第8行にあります。<STDIN>は、mapが入力から1行ずつ取得して{}内の関数を実行する際に、map{}に適用されるファイルハンドルです。(.*):(.*)という式は、コロンで区切られたキャプチャグループのペアから成る正規表現です。サーバから送信されるキーそれ自体のなかにコロンが含まれることはないので、前方の.*だけでは一致しません。ほとんどの印字不能文字(改行文字など)は、ディクショナリー内ではパーセントエンコーディングで符号化されているため、トリガは1組のキー/値が1行で記述されることを前提とします。したがって単一の正規表現は、キーと値の両方を抽出します。正規表現の戻り値は、文字列のリストであり、マップ関数の戻り値として扱われます。リストがハッシュに割り当てられると、Perlはそこからキー/値のペアのリストの作成を試みます。ご存知のようにそのリストは偶数項目から成っているので、この試行は成功し、データを取得できました。printコマンドが結果ディクショナリーを作成し、それをサーバに送信します。そのコマンドを呼び出すと、パスアクションによって、サーバは、コマンド続行を許可し、トリガの入力ディクショナリーのフォーマット済みハッシュをメッセージとしてユーザに送信するようにという指示を受け取ります。

例外

triggers.io に1を指定したとしても、認証トリガやアーカイブトリガには影響しません。これらのトリガは、あたかも、実際に設定されている値とは無関係に、あたかもtriggers.ioに0が指定されているかのように動作します。

古いトリガとの互換性

triggers.io変数に1を設定すると、サーバで実行されるすべての新旧のスクリプトの動作に影響を及ぼします。古いトリガスクリプトの書き直しを望まない場合、シムを、トリガテーブルと古いトリガスクリプトの間に挿入することにより、トリガ出力を収集し、それをサーバで現在取り扱っているとおりにフォーマットするとよいでしょう。すなわち、シムが古いトリガを実行し、その出力とリターンコードを取得した後で、適切なディクショナリーをサーバに送り返します。以下のPerlスクリプトで、そのようなシムの具体例を示します。

t form-out label unset "perl shim.pl original_trigger.exe orig_args..."

shim.plプログラムは、以下のように表示されます。

use strict;
use warnings FATAL => "all";
use open qw/ :std :utf8 /;
use URI::Escape;
use IPC::Run3;

@_=<STDIN>;
run3 \@ARGV, undef, \$_, \$_;
print 'action:' . (? ? 'fail' : 'pass' ) . "\nmessage:" . uri_escape $_;

複数のトリガを使用する

サブミットトリガとフォームトリガは、トリガテーブルに登場する順序で実行されます。同じタイプに属する複数のトリガが同じパスに対して実行される場合、各トリガはトリガテーブルに登場する順序で実行されます。これらのトリガのうち1つが失敗すると、それ以降のトリガは実行されません。

Example 10. 同じファイル上の複数のトリガ

すべての*.cファイルは、スクリプトcheck1.shcheck2.shcheck3.shを通じて渡される必要があります。

Triggers:
  check1 change-submit //depot/src/*.c "/usr/bin/check1.sh %change%"
  check2 change-submit //depot/src/*.c "/usr/bin/check2.sh %change%"
  check3 change-submit //depot/src/*.c "/usr/bin/check3.sh %change%"

ひとつでもトリガ(例えばcheck1.sh)が失敗した場合、サブミットはただちに失敗し、後続のすべてのトリガ(check2.shcheck3.sh)が呼び出されなくなります。トリガが成功するたびに、次の一致するトリガが実行されます。

複数のファイル仕様を同じトリガ(およびトリガタイプ)にリンクするには、トリガテーブル中にトリガを複数回記入します。

Example 11. 複数のファイル仕様に対して同一のトリガをアクティベートする

Triggers:
  bugcheck change-submit //depot/*.c   "/usr/bin/check4.sh %change%"
  bugcheck change-submit //depot/*.h   "/usr/bin/check4.sh %change%"
  bugcheck change-submit //depot/*.cpp "/usr/bin/check4.sh %change%"

上記の例では、bugcheckトリガが、*.cファイル、*.hファイル、*.cppファイルに対して実行されます。

異なるタイプに属する複数のサブミットトリガを同一のパスに対して実行すると、以下の順序で実行されます。

  1. change-submit(ファイルの転送を行う前に、チェンジリストのサブミットを実行する時)

  2. change-contentトリガ(チェンジリストのサブミットとファイルの転送の後)

  3. change-commitトリガ(サーバによって、チェンジリストの番号が自動的に振り直された時)

同様に、異なるタイプに属する複数のフォームトリガは、以下の順序で実行されます。

  1. form-out(フォームが生成された時)

  2. form-in(変更されたフォームがサーバに転送された時)

  3. form-save(検証済みのフォームがPerforceデータベース内のストレージに保存される前)

  4. form-delete(検証済みのフォームがPerforceデータベース内のストレージに保存された後)

複数のPerforceサーバをサポートするトリガを作成する

同一のトリガスクリプトを2つ以上のPerforceサーバから呼び出すには、%serverhost%%serverip%%serverport%変数を使用して、トリガスクリプトを他のサーバでも使用できるようにします。

例えば、ハードコーディングされたポート番号とアドレスを使用する以下のようなスクリプトがあるとします。

#!/bin/sh
# Usage: jobcheck.sh changelist
CHANGE=$1
P4CMD="/usr/local/bin/p4 -p 192.168.0.12:1666"
$P4CMD describe -s $1 | grep "Jobs fixed...\n\n\t" > /dev/null

そして上記のスクリプトを、トリガテーブル内の以下の行で呼び出すとします。

jc1 change-submit //depot/qa/... "jobcheck.sh %change%"

そのスクリプトのポータビリティーを向上するには、スクリプトを以下のように変更します。

#!/bin/sh
# Usage: jobcheck.sh changelist server:port
CHANGE=$1
P4PORT=$2
P4CMD="/usr/local/bin/p4 -p $P4PORT"
$P4CMD describe -s $1 | grep "Jobs fixed...\n\n\t" > /dev/null

そして、サーバ固有のデータを、引数としてトリガスクリプトに渡します。

jc2 change-submit //depot/qa/... "jobcheck.sh %change% %serverport%"

注意: %serverport%変数には、トランスポートプレフィックスが含まれることがあります。すなわち、ssltcp6ssl6のことです。

各トリガタイプごと適用する変数を網羅したリストについては、トリガスクリプト変数を参照してください。

トリガと分散アーキテクチャ

マスターサーバにインストールされているトリガは、そのレプリカサーバのすべてに存在している必要があります。レプリカにインストールされているトリガは、そのトリガに対する同一の実行環境とトリガ本体を持っている必要があります。トリガ本体には、通常、トリガログインチケット、PrelやPythonのようなトリガスクリプトランタイムが含まれています。

サブミットに対してトリガを起動させる

ユーザがチェンジリストをサブミットした時点でPerforceがトリガスクリプトを実行するように構成するには、サブミットトリガを使用します。こうしたタイプのトリガとしては、change-submitchange-contentchange-commitがあります。p4 submitまたはp4 populateコマンドの場合、change-failed トリガも使用することができます。

サブミットと連動したファイルのロック動作を考慮したほうがよい場合があります。すなわち、チェンジリストをコミットする前に、 p4 submitが、サブミットされているすべてのファイルをロックする動作のことです。ロックもサブミットもされないファイルが存在する場合、そのファイルは番号付き作業中チェンジリストにおいて作業状態のままになります。デフォルトでは、サブミット操作に失敗したファイルは、submit.unlocklocked構成可能変数が設定されていない限り、ロックされたままになります。サブミットに失敗した場合、たとえサブミット前に手動でロックされていたとしても、submit.unlocklockedが設定されていれば、ファイルのロックは解除されます。

以下の表では、サブミットトリガに関するフィールドについて説明します。サンプルの定義に関しては、トリガの各サブタイプについて説明している後続のセクションを参照してください。

フィールド

意味

type

  • change-submit: チェンジリストの作成後、かつファイルの転送前に、サブミットトリガを実行します。トリガはファイルの内容にアクセスできません。

  • change-content: チェンジリストの作成およびファイルの転送後、かつファイルのコミット前に、サブミットトリガを実行します。

    ファイルの内容を取得するには、リビジョン指定子@=change(そのうちchange%changelist%変数でスクリプトに渡される作業中チェンジリストのチェンジリスト番号)を、p4 diff2p4 filesp4 fstatp4 printなどのコマンドとともに使用します。

  • change-commit: チェンジリストの作成、ファイルの転送、ファイルのコミットが行われた後に、サブミットトリガを実行します。

  • change-failed: p4 submitまたはp4 populateコマンドが失敗した場合に、サブミットトリガを実行します。このトリガは、コミット処理の開始後にエラーが発生した場合のみ起動します。早期使用によるエラーや、サブミットフォームからのエラーによっては、起動しません。すなわち、エッジまたはチェンジトリガが実行された後、そのコミットが失敗した場合にchange-failedトリガが起動します。

path

ディポシンタックスのファイルパターンです。

ユーザがこのファイルパターンに一致するファイルを含むチェンジリストをサブミットすると、commandフィールドで指定されたトリガが実行されます。特定のファイルに対してトリガが実行されるのを防ぐには、排他的マッピングを使用します。

command

このPerforceサーバ向けトリガは、ユーザがpathで指定されているファイルパターンを含むチェンジリストをサブミットすると実行されます。Perforceサーバアカウントがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl //depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

change-submitおよびchange-contentトリガ(ならびにそれらの対応するエッジサーバトリガ)に関しては、トリガが失敗した場合、チェンジリストのサブミットは続行されません。change-commitトリガに関しては、チェンジリストのサブミットはトリガの成否にかかわらず正常に行われますが、スクリプト実行に失敗した場合は後続のchange-commitトリガは起動しません。

たとえchange-submitまたはchange-contentトリガスクリプトが成功したとしても、後続のトリガの失敗やその他の要因により、サブミットに失敗する場合があります。change-submitおよびchange-contentトリガは、検証ためのみに使用してください。また、change-commitトリガまたはデーモンは、サブミットの正常な完了を条件とする操作のために使用してください。

特殊なケースに注意してください。例えば、クライアントワークスペースにrevertunchangedオプションセットがあり、かつユーザが変更されたファイルのないチェンジリストに対してp4 submitを実行した場合、チェンジリストはファイルの内容とともにサブミットされてしまいますが、変更は実際にはコミットされません。(すなわち、change-submitトリガとchange-contentトリガは起動しますが、change-commitトリガは起動しないということです。)

change-submitトリガ

チェンジリストの作成後、かつサーバへのファイルの転送前に起動するトリガを作成するには、change-submitトリガタイプを使用します。change-submitトリガは、ファイルがサーバに転送される前に起動するので、ファイルの内容にアクセスできません。change-submitトリガは、ファイルの内容へのアクセスを必要としないレポートツールまたはシステムとの統合に役立ちます。

p4 submitコマンドに加えて、p4 populateコマンドは、自らのブランチングアクションの一環として暗黙的なサブミットを実行するコマンドであり、change-submitトリガを起動させてサブミット前の検証を可能にします。

Example 12. 以下のchange-submitトリガは、サブミットしたユーザがチェンジリストにジョブを割り当てていなかった場合に、チェンジリストを拒否するMS-DOSバッチファイルです。このトリガは、//depot/qaブランチ内の少なくとも1つのファイルに影響するチェンジリストのサブミット試行に対してのみ起動します。

@echo off

rem REMINDERS
rem - If necessary, set Perforce environment vars or use config file
rem - Set PATH or use full paths (C:\PROGRA~1\Perforce\p4.exe)
rem - Use short pathnames for paths with spaces, or quotes
rem - For troubleshooting, log output to file, for instance:
rem - C:\PROGRA~1\Perforce\p4 info >> trigger.log

if not x%1==x goto doit
echo Usage is %0[change#]

:doit
p4 describe -s %1|findstr "Jobs fixed...\n\n\t" > nul
if errorlevel 1 echo No jobs found for changelist %1
p4 describe -s %1|findstr "Jobs fixed...\n\n\t" > nul

このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample1   change-submit //depot/qa/...   "jobcheck.bat %changelist%"

チェンジリストがサブミットされるたびに、//depot/qa以下のすべてのファイルに影響し、jobcheck.batが呼び出されます。Jobs fixed...という文字列(およびその後に改行文字2つとタブ文字)が検出された場合、スクリプトは、1つのジョブがすでにチェンジリストに組み込まれていると想定し、チェンジリストのサブミットの続行を許可します。この文字列が検出されなければ、サブミットは拒否されます。

2つめのfindstrコマンドは、トリガスクリプトの最終エラーレベルが、エラーメッセージを出力するかどうか決定するエラーレベルと同じであることを確認します。

change-contentトリガ

チェンジリスト作成とファイル転送の後、かつデータベースにサブミットをコミットする前に起動するトリガを作成するには、change-contentトリガタイプを使用します。change-contentトリガは、p4 diff2p4 filesp4 fstatp4 print@=changeリビジョン指定子を付けて使用することにより、ファイルの内容にアクセスすることができます。その場合、changeは、%changelist%変数でトリガスクリプトに渡される作業中チェンジリストの番号です。

change-contentトリガを使用すると、チェンジリストのサブミットの一環としてファイルの内容を検証し、検証に失敗した場合はチェンジリストのサブミットを中断することができます。

たとえchange-submitまたはchange-contentトリガスクリプトが成功したとしても、後続のトリガーの失敗やその他の要因により、サブミットに失敗する場合があります。change-submitおよびchange-contentトリガは、検証ためのみに使用してください。また、change-commitトリガまたはデーモンは、サブミットの正常な完了を条件とする操作のために使用してください。

Example 13. 以下のchange-contentトリガは、すべてのチェンジリストに含まれるすべてのファイルに現在の年の著作権情報が含まれていることを確認するBourneシェルスクリプトです。

このスクリプトは、//depot/srcのすべてを含むcopycheckerという名前のクライアントワークスペースの存在を想定しています。このワークスペースは、同期されている必要はありません。

#!/bin/sh
# Set target string, files to search, location of p4 executable...
TARGET="Copyright 'date +%Y' Example Company"
DEPOT_PATH="//depot/src/..."
CHANGE=$1
P4CMD="/usr/local/bin/p4 -p 1666 -c copychecker"
XIT=0
echo ""
# For each file, strip off #version and other non-filename info
# Use sed to swap spaces w/"%" to obtain single arguments for "for"
for FILE in '$P4CMD files $DEPOT_PATH@=$CHANGE | \
  sed -e 's/\(.*\)\#[0-9]* - .*$/\1/' -e 's/ /%/g''
do
  # Undo the replacement to obtain filename...
  FILE="'echo $FILE | sed -e 's/%/ /g''"
# ...and use @= specifier to access file contents:
  # p4 print -q //depot/src/file.c@=12345
  if $P4CMD print -q "$FILE@=$CHANGE" | grep "$TARGET" > /dev/null
  then echo ""
  else
      echo "Submit fails: '$TARGET' not found in $FILE"
      XIT=1
  fi
done
exit $XIT

このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample2  change-content //depot/src/... "copydate.sh %change%"

このトリガは、//depot/src内のファイルを少なくとも1つ含むチェンジリストがサブミットされると起動します。スクリプト中で定義された対応するDEPOT_PATHにより、トリガ対象であるチェンジリスト中のすべてのファイルのうち、現在//depot/srcの下にあるファイルだけがチェックされます。

change-commitトリガ

チェンジリストの作成、ファイルの転送、データベースに対するチェンジリストのコミットが完了した後に起動するトリガを作成するには、change-commitトリガタイプを使用します。チェンジリストのサブミットが正常に完了したことを想定(または必要と)するプロセスに対しては、change-commitトリガを使用します。

Example 14. 以下のchange-commitトリガは、サブミットされたチェンジリスト内のファイルを作業状態にしている他のユーザに対して、電子メールを送信します。

#!/bin/sh
# mailopens.sh - Notify users when open files are updated
changelist=$1
workspace=$2
user=$3
p4 fstat @$changelist,@$changelist | while read line
do
  # Parse out the name/value pair.
  name='echo $line | sed 's/[\. ]\+\([^ ]\+\) .\+/\1/''
  value='echo $line | sed 's/[\. ]\+[^ ]\+ \(.\+\)/\1/''
  if [ "$name" = "depotFile" ]
  then
    # Line is "... depotFile <depotFile>". Parse to get depotFile.
    depotfile=$value
  elif [ "'echo $name | cut -b-9'" = "otherOpen" -a \
    "$name" != "otherOpen" ]
  then
    # Line is "... ... otherOpen[0-9]+ <otherUser@otherWorkspace>".
    # Parse to get otherUser and otherWorkspace.
    otheruser='echo $value | sed 's/\(.\+\)@.\+/\1/''
    otherworkspace='echo $value | sed 's/.\+@\(.\+\)/\1/''
    # Get email address of the other user from p4 user -o.
    othermail='p4 user -o $otheruser | grep Email: \
      | grep -v \# | cut -b8-'

    # Mail other user that a file they have open has been updated
    mail -s "$depotfile was just submitted" $othermail <<EOM
The Perforce file: $depotfile
was just submitted in changelist $changelist by Perforce user $user
from the $workspace workspace.  You have been sent this message
because you have this file open in the $otherworkspace workspace.
EOM
  fi
done
exit 0

このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample3  change-commit //... "mailopens.sh %change% %client% %user%"

ユーザがチェンジリストをサブミットするたびに、そのチェンジリストから影響を受ける作業状態のファイルを持つすべてのユーザが、電子メール通知を受信します。

コマンドの前または後にトリガを起動させる

commandタイプのトリガにより、Perforceを設定して、任意のコマンドが実行される前後にトリガを実行させることができます。一般的に、コマンドが実行される前にスクリプトを実行することにより、そのコマンドの実行を防ぐことが望ましい場合や、コマンドが実行された後にスクリプトを実行することにより、そのアクションを他のツールまたはプロセスにつなげることが望ましい場合があるものです。

Note

コマンドタイプのトリガをp4 pushおよびp4 fetchコマンドと組み合わせて使用することができます。

以下の表では、commandトリガに関するフィールドについて説明します。

フィールド

意味

type

command

実行されるべきコマンドは、pathフィールドで指定されます。

path

pre-user-commandの値には、トリガ起動に先立って実行されるべきコマンドを指定します。post-user-commandの値には、トリガ起動に引き続き実行されるべきコマンドを指定します。commandは正規表現を使用できます。正規表現の文法に関する補足情報については、p4 help grepを参照してください。

実際に使用されやすいパス値の例を以下に挙げます。

pre-user-login           \\ before the login command
post-user-(add|edit)     \\ after the add or edit command
pre-user-obliterate      \\ before the obliterate command
(pre|post)-user-sync     \\ before or after the sync command

他の有効なコマンドの部分文字列に相当するコマンド名を照合する場合、行末メタ文字を使用して照合を終了させる必要があります。例えば、change$を使用すると、changesの照合まで行わずに済みます。

pre-user-infoトリガは作成できません。

command

このPerforceサーバ向けトリガは、pathによって暗黙的に指定された条件が満たされると、実行されます。

Perforceサーバがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲む必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl //depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

コマンドトリガ内でやるべきことのひとつに、入力ディクショナリーの解析を挙げることができます。以下のコードサンプルではまさにそれを行います。保存されているキー/値をアクセス待機中のPerlデータ構造内に置くと、データをサーバに送り返す方法が示されます。

use strict
use warnings FATAL => "all";
use open qw / :std :utf8 /;
use Data::Dumper;
use URI::Escape;

$Data::Dumper::Quotekeys = 0;
$Data::Dumper::Sortkeys = 1;

my %keys = map { /(.*):(.*)/ } <STDIN>;

print "action:pass\nmessage:"  . uri_escape Dumper \ %keys;

上記のソースリストは必要な範囲よりも少し長く前後の行まで記載していますが、これは望ましいトリガコードの作成方法を説明するためです。ソースリストの冒頭では、いくつかのコードによってUnicodeの基本サポートのためにPerlを設定し、さらに少々のエラー処理を加えています。プログラムの核心は第8行にあります。<STDIN>は、mapが入力から1行ずつ取得して{}内の関数を実行する際に、map{}に適用されるファイルハンドルです。(.*):(.*)という式は、コロンで区切られたキャプチャグループのペアから成る正規表現です。サーバから送信されるキーそれ自体のなかにコロンが含まれることはないので、前方の.*だけでは一致しません。ほとんどの印字不能文字(改行文字など)は、ディクショナリー内ではパーセントエンコーディングで符号化されているため、トリガは1組のキー/値が1行で記述されることを前提とします。したがって単一の正規表現は、キーと値の両方を抽出します。正規表現の戻り値は、文字列のリストであり、マップ関数の戻り値として扱われます。リストがハッシュに割り当てられると、Perlはそこからキー/値のペアのリストの作成を試みます。ご存知のようにそのリストは偶数項目から成っているので、この試行は成功し、データを取得できました。

printコマンドが結果ディクショナリーを作成し、それをサーバに送信します。そのコマンドを呼び出すと、パスアクションによって、サーバは、コマンド続行を許可し、トリガの入力ディクショナリーのフォーマット済みハッシュをメッセージとしてユーザに送信するようにという指示を受け取ります。

スクリプトの記述後、p4 triggersフォームを編集することにより、記述したスクリプトをトリガテーブルに追加することができます。

Triggers:
  myTrig command  post-user-move "perl /usr/bin/test.pl "

p4 moveコマンドの実行後に、このトリガが起動します。

保留中のイベントに対してトリガを起動させる

ユーザが保留状態のファイルを操作した時点でPerforceがトリガスクリプトを実行するように構成するには、保留トリガを使用します。このタイプのトリガとしては、shelve-submitshelve-commitshelve-deleteがあります。

以下の表では、保留タイプトリガに関するフィールドについて説明しています。

フィールド

意味

type

  • shelve-submit: チェンジリストの作成およびファイルのロック後、かつファイルの転送前に、保留前トリガを実行します。

  • shelve-commit: ファイルが保留されてから、保留後トリガを実行します。

  • shelve-delete: 保留状態のファイルを破棄する前に、保留トリガを実行します。

path

ディポシンタックスのファイルパターンです。

指定したパス内のファイルがシェルフに含まれている場合、トリガが起動します。保留操作によってこれらのトリガを起動させないようにするには、パス内で排他的マッピングを使用します。

command

このPerforceサーバ向けトリガは、pathとの照合がそのトリガタイプに適用されると実行されます。Perforceサーバアカウントがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl %//depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

shelve-submitトリガ

shelve-submitトリガはchange-submitトリガに似た動作を示します。つまり、保留状態のチェンジリストが作成された後、かつファイルがサーバへ転送される前に起動します。shelve-submitトリガは、ファイルの内容へのアクセスを必要としないレポートツールまたはシステムとの統合に役立ちます。

Example 15. サイトの管理者としては、大規模ディスクイメージの保留を禁止したいところです。以下のshelve-submitトリガは、チェンジリストに.isoファイルが含まれている場合、保留の操作を拒否します。

#!/bin/sh

# shelve1.sh - Disallow shelving of certain file types

# This trigger always fails: when used as a shelve-submit trigger
# with a specified path field, guarantees that files matching that
# path are not shelved

echo "shelve1.sh: Shelving operation disabled by trigger script."

exit 1

このトリガを使用するには、以下の行をトリガテーブルに追加し、どのパスに対する保留が禁止されるべきかを適切なフィールド内に指定します。

shelving1   shelve-submit   //....iso   shelve1.sh

チェンジリストがサブミットされるたびに、ディポ内のあらゆる.isoファイルに影響を及ぼし、noshelve.shスクリプトが実行され、ディスクイメージファイルの保留リクエストを拒否します。

shelve-commitトリガ

保留およびファイルの転送後に起動するトリガを作成するには、shelve-commitトリガタイプを使用します。保留操作のサブミットが正常に完了したことを想定(または必要と)するプロセスに対しては、shelve-commitトリガを使用します。

Example 16. shelve-commitトリガは、保留状態のチェンジリストに関してユーザ(この場合はreviewers)に通知します。

#!/bin/sh
# shelve2.sh - Send email to reviewers when open files are shelved
changelist=$1
workspace=$2
user=$3

mail -s "shelve2.sh: Files available for review" reviewers << EOM
   $user has created shelf from $workspace in $changelist"
EOM

exit 0

このトリガを使用するには、以下の行をトリガテーブルに追加します。

shelving2  shelve-commit //... "shelve2.sh %change% %client% %user%"

ユーザがチェンジリストを保留状態にするたびに、レビュー担当者は電子メール通知を受信します。

shelve-deleteトリガ

ユーザが保留状態のファイルを破棄した後に起動するトリガを作成するには、shelve-deleteトリガを使用します。

Example 17. 保留状態のファイルが破棄されたことをレビュー担当者に通知するshelve-deleteトリガ。

#!/bin/sh
# shelve3.sh - Send email to reviewers when files deleted from shelf
changelist=$1
workspace=$2
user=$3

mail -s "shelve3.sh: Shelf $changelist deleted" reviewers << EOM
   $user has deleted shelved changelist $changelist"
EOM

exit 0

このトリガを使用するには、以下の行をトリガテーブルに追加します。

shelving3  shelve-delete //... "shelve3.sh %change% %client% %user%"

ユーザがシェルフからファイルを削除するたびに、レビュー担当者は電子メール通知を受信します。より実際に即した例では、外部(または内部)のデータソースをチェックし、保留状態のファイルの削除をユーザに許可する前にコードレビューが完了しているかどうか検証するとよいでしょう。

修正に対してトリガを起動させる

ユーザがチェンジリストで修正を追加または削除した時点でPerforceがトリガスクリプトを実行するように構成するには、修正トリガを使用します。こうしたタイプのトリガとしては、fix-addfix-deleteがあります。

特殊変数%jobs%は、修正トリガの拡張として使用できます。この特殊変数は、p4 fixコマンドライン上で(またはp4 changeまたはp4 submitフォームのJobs:フィールド内で)リスト表示されるジョブごとに1つの引数に拡張されます。したがって、この特殊変数は、トリガスクリプトに提供される引数のなかでは最後に置かれる必要があります。

以下の表では、修正トリガの定義に使用されるフィールドについて説明します。

フィールド

意味

type

  • fix-add: 修正を追加する前に修正トリガを実行します。

  • fix-delete: 修正を削除する前に修正トリガを実行します。

path

fixはパス値として使用します。

command

このPerforceサーバ向けトリガは、ユーザが修正を追加または削除すると実行されます。Perforceサーバアカウントがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl %//depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

fix-addおよびfix-deleteトリガの場合、スクリプトが成功したにせよ失敗したにせよ、修正の追加または削除が続行されます。

Fix-addトリガとfix-deleteトリガ

Example 18. 以下のスクリプトをfixadd.shおよびfixdel.shにコピーしておくと、ユーザがp4 fixコマンドを使用するか、p4 changeおよびp4 submitによって提示されるフォームのJobs:フィールドを変更することにより、修正レコードの追加または削除を試みた時点で、トリガが起動します。

#!/bin/bash
# fixadd.sh, fixdel.sh - illustrate fix-add and fix-delete triggers

COMMAND=$0
CHANGE=$1
NUMJOBS=$(($# - 1 ))

echo $COMMAND: fired against $CHANGE with $NUMJOBS job arguments.
echo $COMMAND: Arguments were: $*

これらfix-addおよびfix-deleteトリガは、ユーザがチェンジリストからの修正レコードの追加(または削除)を試みるたびに起動します。このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample4   fix-add    fix "fixadd.sh %change% %jobs%"
sample5   fix-delete fix "fixdel.sh %change% %jobs%"

スクリプトのコピーの両方を使用して、次のことを確認してください。まず、fixadd.shp4 fixによって起動されること。また、fixdel.shスクリプトがp4 fix -dによって起動されること。さらに、いずれかのスクリプトがp4 changeを介して、あるいはp4 submitプロセスの一環として、チェンジリストフォーム中のJobs:フィールド内からジョブ番号を手動で追加(または削除)することによって起動されることです。

%jobs%変数は、p4 fixコマンドライン上で(またはp4 changeあるいはp4 submitフォームのJobs:フィールド内で)リスト表示されるジョブ1つにつき、1つの引数に展開されます。したがってこの変数は、fix-addまたはfix-deleteトリガスクリプトに渡される引数のうち、最後に置かれる必要があります。

フォームに対してトリガを起動させる

ユーザがフォームを編集した時点でPerforceがトリガスクリプトを実行するように構成するには、フォームトリガを使用します。こうしたタイプのトリガとしては、form-saveform-inform-outform-deleteform-commitがあります。

フォームトリガを使用すると、ユーザ向けにカスタマイズされたフィールド値を生成したり、フォーム上で提供されたデータを検証したり、フォームデータの変更が試みられた場合に他のユーザに通知したり、プロセスの制御および管理ツールと交信することができます。

トリガフォームに対して起動するトリガを記述し、そのトリガが失敗してp4 triggersコマンドがもはや機能しない状態になった場合、最終手段としてサーバルートディクショナリー内のdb.triggersファイルを削除するしかありません。

以下の表では、フォームトリガの定義に関するフィールドについて説明します。

フィールド

意味

type

  • form-save: フォームの内容が解析された後、かつその内容がPerforceデータベースに保存される前にフォームトリガを実行します。トリガは%formfile%変数で指定されたフォームを修正できません。

  • form-out: フォームがエンドユーザへ生成されると、ただちにフォームトリガを実行します。トリガはフォームを修正できます。

  • form-in: フォームの内容がPerforceサーバによって解析され、検証される前に、編集されたフォームに対してフォームトリガを実行します。トリガはフォームを修正できます。

  • form-delete: フォームの内容が解析された後、かつそのフォームがPerforceデータベースから削除される前にフォームトリガを実行します。トリガはフォームを修正できません。

  • form-commit: 自動生成されたフィールド(ジョブ名、日付など)へのアクセスのためにフォームがコミットされた後に、フォームトリガを実行します。

path

フォームのタイプ名です(branchchangeclientdepotgroupjoblabelprotectserverspecstreamtriggerstypemapuser)。

command

このPerforceサーバ向けトリガは、pathフィールド内で指定しておいたフォームのタイプが処理されると実行されます。

Perforceサーバアカウントがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl %//depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

form-inform-outform-saveform-deleteトリガの場合、スクリプトが成功すると仕様にあるデータがPerforceデータベースの一部に組み込まれます。失敗した場合、データベースは更新されません。

Warning

Name:フィールドがp4sandbox-で開始するクライアントワークスペース仕様には、(名前にせよ内容にせよ)いかなる変更も加えてはいけません。変更した場合、P4Sandboxが共有リポジトリと適切に連動できなくなります。

フォームトリガを作成および管理する場合、以下のことに注意してください。

  • P4Sandboxクライアント仕様を修正する可能性があるフォームトリガスクリプトを新たに作成してはいけません。

  • P4Sandboxクライアント仕様を修正する可能性があるフォームトリガスクリプトがすでに存在している場合、その動作を防止するようにスクリプトを変更する必要があります。例えば、スクリプトを調整して、%client%変数がスクリプトに渡されるとただちに、その変数を検証するように設定します。ユーザのクライアントワークスペース仕様のName:フィールドがp4sandbox-で開始する場合、トリガは以下の動作のうち1つを実行する必要があります。

  • フォームトリガがいかなるp4sandbox-ワークスペースに対しても無条件で失敗するようにしてください。これにより、ユーザが管理中のサーバでP4Sandboxを使用することを防止できます。

  • フォームトリガがクライアントワークスペース仕様を修正することなく成功するようにしてください。管理者の属する組織におけるすべてのユーザが、管理中のサーバをP4Sandboxリモートディポとして使用することができます。

詳細については、『Perforceサンドボックスユーザガイド』の「P4Sandboxを管理する」を参照してください。

form-saveトリガ

ユーザが変更されたフォームをサーバに送信すると起動するトリガを作成するには、form-saveトリガタイプを使用します。form-saveトリガが呼び出されるタイミングは、フォームがサーバによって解析された後、かつ変更されたフオームがPerforceメタデータに保存される前です。

Example 19. 特定のユーザが各自のクライアントワークスペースを修正できないようにするには、そのユーザをlockedwsというグループに追加し、以下のform-saveトリガを使用します。

このトリガは、lockedwsグループのユーザによるクライアントワークスペース仕様変更の試行を拒否します。そして、ユーザ名、ユーザワークステーションのIPアドレス、修正の試行の対象となったワークスペース名を含むエラーメッセージを出力し、管理者に通知します。

#!/bin/bash
NOAUTH=lockedws
USERNAME=$1
WSNAME=$2
IPADDR=$3

GROUPS='p4 groups "$1"'

if echo "$GROUPS" | grep -qs $NOAUTH
then
   echo "$USERNAME ($IPADDR) in $NOAUTH may not change $WSNAME"
   mail -s "User $1 workspace mod denial" admin@127.0.0.1
   exit 1
else
   exit 0
fi

このform-saveトリガは、clientフォームに対してのみ起動します。このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample6   form-save  client  "ws_lock.sh %user% %client% %clientip%"

p4 groups lockedwsの出力に登場するユーザ名を持つユーザは、各自のクライアントワークスペースに対する変更をサーバによって解析させようとしますが、たとえそうした変更が構文上適切であったとしても、クライアントワークスペースに対する変更の試行は拒否され、その試行が管理者に通知されます。

form-outトリガ

form-outトリガタイプを使用すると、Perforceサーバがユーザのディスプレイに向けてフォームを生成するたびに起動するトリガを作成することができます。

Warning

form-outトリガ内で、同一のform-outトリガを起動するPerforceコマンドを決して使用してはいけません。使用した場合、無限再帰が発生します。例えば、jobフォームに対して起動するform-outトリガスクリプト内から、p4 job -oを決して実行させないでください。

Example 20. デフォルトのPerforceクライアントワークスペースビューでは、ディポ//depot/...の全体を、ユーザのクライアントワークスペースにマッピングします。ディポ全体の同期を新しいユーザに試行させないようにするために、このPerlスクリプトは、p4 clientフォーム中の//depot/...のデフォルトのワークスペースビューを変更し、//depot/releases/main/...の現在のリリースコードラインのみをマッピングします。

#!/usr/bin/perl
# default_ws.pl - Customize the default client workspace view.
$p4 = "p4 -p localhost:1666";
$formname = $ARGV[0];  # from %formname% in trigger table
$formfile = $ARGV[1];  # from %formfile% in trigger table
# Default server-generated workspace view and modified view
# (Note: this script assumes that //depot is the only depot defined)
$defaultin = "\t//depot/... //$formname/...\n";
$defaultout = "\t//depot/releases/main/... //$formname/...\n";
# Check "p4 clients": if workspace exists, exit w/o changing view.
# (This example is inefficient if there are millions of workspaces)
open CLIENTS, "$p4 clients |" or die "Couldn't get workspace list";
while ( <CLIENTS> )
{
        if ( /^Client $formname .*/ ) { exit 0; }
}
# Build a modified workspace spec based on contents of %formfile%
$modifiedform = "";
open FORM, $formfile or die "Trigger couldn't read form tempfile";
while ( <FORM> )
{       ## Do the substitution as appropriate.
        if ( m:$defaultin: ) { $_ = "$defaultout"; }
        $modifiedform .= $_;
}
# Write the modified spec back to the %formfile%,
open MODFORM, ">$formfile" or die "Couldn't write form tempfile";
print MODFORM $modifiedform;
exit 0;

このform-outトリガは、clientワークスペースフォームに対してのみ起動します。このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample7   form-out  client  "default_ws.pl %formname% %formfile%"

クライアントワークスペースを作成している新しいユーザが、カスタマイズされた既定のビューで表示されます。

form-inトリガ

ユーザがサーバに対してフォームの送信を試みた時点で、かつフォームがPerforceサーバによって解析される前に起動するトリガを作成するには、form-inトリガタイプを使用します。

Example 21. ジョブの編集権限を持つすべてのユーザは、jobbersという所定のグループに配属されます。以下のPythonスクリプトは、p4 group -o jobbersに-G(Python変換オブジェクト)フラグを指定して実行することにより、スクリプトを起動させたユーザがjobbersグループに配属されているかどうか判定します。

import sys, os, marshal

# Configure for your environment
tuser = "triggerman"   # trigger username
job_group = "jobbers"  # Perforce group of users who may edit jobs

# Get trigger input args
user = sys.argv[1]

# Get user list
# Use global -G flag to get output as marshaled Python dictionary
CMD = "p4 -G -u %s -p 1666 group -o %s" % \
        (tuser, job_group)
result = {}
result = marshal.load(os.popen(CMD, 'r'))

job_users = []
for k in result.keys():
        if k[:4] == 'User': # user key format: User0, User1, ...
                u = result[k]
                job_users.append(u)

# Compare current user to job-editing users.
if not user in job_users:
        print "\n\t>>> You don't have permission to edit jobs."
        print "\n\t>>> You must be a member of '%s'.\n" % job_group
        sys.exit(1)
else: # user is in job_group -- OK to create/edit jobs
        sys.exit(0)

このform-inトリガは、jobフォームに対してのみ起動します。このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample8   form-in  job  "python jobgroup.py %user%"

ユーザがjobbersグループに所属している場合、form-inトリガは成功し、変更されたジョブが解析のためにPerforceサーバに渡されます。所属していない場合、エラーメッセージが表示され、ジョブに対する変更は却下されます。

form-deleteトリガ

ユーザがフォームの削除を試み、フォームがPerforceサーバによって解析された後、かつそのフォームがPerforceデータベースから削除される前起動するトリガを作成するには、form-deleteトリガタイプを使用します。

Example 22. 管理者が、ジョブをシステムから削除するのではなく対象のジョブをclosedに変更するという規則を、ユーザに徹底させたいと考えているとします。

#!/bin/sh

echo "Jobs may not be deleted. Please mark jobs as closed instead."
exit 1

このform-deleteトリガは、jobフォームに対してのみ起動します。このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample9   form-delete  job  "nodeljob.sh"

ユーザがジョブの削除を試みると、ジョブの削除要求は拒否され、ユーザに向けてエラーメッセージが表示されます。

Form-commitトリガ

他のフォームトリガとは異なり、form-commitトリガは、フォームがデータベースにコミットされた後で起動します。このトリガは、フォームのサブミットが正常に完了したことを想定(または必要と)するプロセスに対して使用します。ジョブフォームの場合では、ジョブがデータベースにコミットされるまではジョブ名は設定されません。ジョブ作成処理の一部として新しいジョブの名前を取得する方法は、form-commitトリガ以外にはありません。

Example 23. 以下のスクリプトをnewjob.shにコピーすると、スクリプトは、ジョブ作成プロセス中にジョブ名を取得する方法を示すと同時に、ジョブ修正に関するチェンジリストの状態を報告します。

#!/bin/sh
# newjob.sh - illustrate form-commit trigger

COMMAND=$0
USER=$1
FORM=$2
ACTION=$3

echo $COMMAND: User $USER, formname $FORM, action $ACTION >> log.txt

このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample10  form-commit  job   "newjob.sh %user% %formname% %action%"

%action%変数を使用すると、ジョブを操作するユーザがp4 jobを使用してジョブに対する変更を直接的に要求したのか、それともp4 fixのコンテキスト内またはチェンジリストのJobs:フィールド中でジョブを修正することによってジョブに対する変更を間接的に要求したのか、判定することができます。

最もシンプルなケースは、p4 jobコマンドによる新しいジョブの作成(既存のジョブに対する変更)です。トリガが起動し、スクリプトが新しく作成(または編集)されたジョブの名前をユーザに報告します。こうした場合では、%action%変数はnullです。

またこのトリガは、ユーザがジョブをチェンジリストに追加または削除した場合にも起動します。これは、変更されたジョブが、p4 fixp4 fix -dの実行か、またはp4 changep4 submitフォームから提供されたチェンジリストフォームのJobs:フィールドの編集か、そのいずれによって操作されているかを問いません。こうした場合には、%action%変数は、ジョブが追加または削除されるチェンジリストの状態(pendingまたはsubmitted)を保持します。

%action%変数は、常に設定されるとは限らないので、form-commitトリガスクリプトに渡される最後の引数とする必要があります。

エッジサーバに対してトリガを起動させる

リリース2013.2以降、コミットサーバとエッジサーバから成るPerforceサービスの分散構成が可能になりました。クライアントおよびエッジサーバの通信中、またはエッジサーバとコミットサーバ通信中に、エッジサーバに対して起動するトリガが用意されています。詳細については、『Perforceサーバ管理者ガイド: マルチサイト展開』を参照してください。

トリガを起動して外部認証を使用する

外部認証マネージャー(LDAPやActive Directoryなど)と連動するようにPerforceを構成するには、認証トリガ(auth-checkauth-check-ssoservice-checkauth-set)を使用します。こうしたトリガは、p4 loginp4 passwdコマンドに対してそれぞれ起動します。

Note

LDAP仕様の採用により、LDAP認証を有効化することが望ましい場合があります。このオプションが推奨される理由はさまざまです。使用が簡単だから、外部のスクリプトが不要だから、バインドメソッドをより柔軟に定義できるようになるから、LDAPディレクトリにないユーザに対してPerforceの内部ユーザデータベースへの照会による認証を許可できるから、またそのほうがより安全であるからです。詳細については、『Perforceの管理: スーパーユーザのタスク』の章の「認証オプション」を参照してください。

認証トリガがチェンジリストやフォームトリガと異なる点は、認証プロセス中にユーザによって入力されたパスワードが標準入力としてコマンドラインではなく認証スクリプトに提供されることです。(コマンドラインに渡される引数は、%user%%clientip%など、すべてのトリガタイプに共通する引用のみです。)

Warning

トリガをトリガテーブルに追加する際には、トリガ名を正しく入力するように注意してください。入力を誤った場合、すべてのユーザがPerforceから閉め出されるおそれがあります。

実稼働環境中へ配備する前に、トリガおよびトリガテーブルの動作を十分にテストしてください。

サーバへのアクセスを復元するのに支援が必要である場合は、Perforceテクニカルサポートまでご連絡ください。

このマニュアルにおける例は説明のための一例にすぎません。LDAP環境向けのサンプルコードを交えたより詳細な議論については、Perforceナレッジベースの「Setting Up External Authentication Triggers」を参照してください。

http://answers.perforce.com/articles/KB_Article/Setting-Up-External-Authentication-Triggers

auth-check(またはservice-check)トリガを有効に動作させるには、追加後にPerforceサーバを再起動する必要があります。ただし、サーバを再起動せずに既存のauth-checkトリガテーブルのエントリ(またはトリガスクリプト)を変更することもできます。

auth-checkトリガの設置およびサーバの再起動が完了すると、その後ではPerforcesecurity構成可能変数は無視されるようになります。これは、認証がトリガスクリプトによって制御されるようになり、パスワード強度の要求に対するサーバのデフォルトのメカニズムは冗長であるからです。

以下の表では、認証トリガの定義に関するフィールドについて説明します。

フィールド

意味

type

  • auth-check: 認証チェックトリガを実行し、ログイン中または新しいパスワードの設定時にユーザのパスワードを外部パスワードマネージャーに照会して検証します。auth-checkトリガが存在する場合、認証はトリガスクリプトによって制御されるようになっているため、Perforceの構成可能変数security(および関連のパスワード強度要件)は無視されます。

    auth-checkトリガを追加したら、Perforceサーバを再起動する必要があります。

  • auth-check-sso: シングルサインオンによるユーザ認証に役立ちます。

  • auth-set: 認証チェックセットトリガを実行し、新しいパスワードを外部パスワードマネージャーに送信します。

  • service-check: トリガを実行し、標準ユーザではなくサービスユーザ(またはオペレータユーザ)のパスワードを検証します。サービスチェックトリガは、auth-checkトリガと同様に動作しまする

    service-checkトリガを追加したら、Perforceサーバを再起動する必要があります。

path

authはパス値として使用します。

command

Perforceサーバを実行するトリガです。トリガが起動するタイミングについてより詳しい情報を知りたい場合は、個別の認証トリガタイプに関して説明している後方のセクションを参照してください。大半の場合、p4 loginコマンドが実行されるときに起動します。

Perforceサーバアカウントがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl %//depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

auth-checkおよびservice-checkトリガが標準ユーザまたはサービスユーザかオペレータユーザによってp4 loginから起動されると、ユーザによって入力されたパスワードは標準入力としてトリガコマンドに供給されます。トリガが正常に起動すると、Perforceチケットが発行されます。ユーザ名は%user%としてコマンドラインで渡すことによって使用できます。

auth-check-ssoトリガが任意のユーザによってp4 loginから起動されると、(P4LOGINSSOによって指定されている)クライアントサイドのスクリプトの出力はプレーンテキストとしてサーバ側スクリプトへ送られます。

auth-setトリガがauth-checkトリガチェックを通過し、かつその後にp4 passwdによって起動されると、ユーザの古いパスワードと新しいパスワードは標準入力としてトリガに渡されます。ユーザ名は%user%としてコマンドラインで渡すことによって使用できます。

auth-checkトリガおよびservice-checkトリガ

標準ユーザがp4 loginコマンドを実行すると、auth-checkタイプのトリガが起動します。同様に、サービスユーザまたはオペレータユーザがp4 loginコマンドを実行すると、service-checkトリガが起動します。スクリプトが0を返すと、ログインは正常に完了し、そのユーザに対するチケットファイルが作成されます。

service-checkトリガの機能はauth-checkトリガとよく似ていますが、その適用対象はType:serviceに設定されているユーザに限られます。service-checkトリガタイプが使用されるのは、Perforce管理者が複製環境やその他のマルチサーバ環境において他のPerforceサーバを認証するためにLDAPを使用したい場合です。

Warning

auth-checkトリガを使用している場合、Perforceスーパーユーザはリモート認証データベースに照会して認証することもできなければなりません。(Perforceスーパーユーザとしてこのトリガを使用できない場合、管理下のサーバからロックされてしまうおそれがあります。その場合、状況を打開するには、常にパスするスクリプトによって一時的にauth-checkトリガを上書きしてください。)

Example 24. ごく簡単な認証チェックスクリプトを以下に示します。

すべてのユーザは、ログインチケット発行前にパスワード"secret"を入力する必要があります。ユーザによって提供されたパスワードは、STDINでスクリプトに送信されます。

#!/bin/bash
# checkpass.sh - a trivial authentication-checking script

# in this trivial example, all users have the same "secret" password
USERNAME=$1
PASSWORD=secret

# read user-supplied password from stdin
read USERPASS

# compare user-supplied password with correct password
if [ "$USERPASS" = $PASSWORD ]
then
    # Success
    exit 0
fi

# Failure
echo checkpass.sh: password $USERPASS for $USERNAME is incorrect
exit 1

このauth-checkトリガは、ユーザがp4 loginを実行すると必ず起動します。このトリガを使用するには、以下の行をトリガテーブルに追加します。

sample11  auth-check  auth  "checkpass.sh %user%"

"secret"パスワードを入力したユーザにログインチケットが発行されます。

シングルサインオンとauth-check-ssoトリガ

auth-check-ssoタイプのトリガは、標準ユーザがp4 loginコマンドを実行すると起動します。それによって2つのスクリプトが実行されます。まずクライアント側スクリプトがユーザのワークステーション上で実行され、次いでその出力がPerforceサーバに(プレーンテキストで)渡され、それからサーバ側スクリプトが実行されます。

  • ユーザのワークステーションで実行されるクライアント側スクリプトの場所は環境変数P4LOGINSSOで指定します。実行されたスクリプトは、ユーザの資格情報か、Perforceサーバによって検証できるその他の情報を取得します。P4LOGINSSOの内容は、クライアント側スクリプト名と、%user%%serverAddress%%P4PORT%のうち0~複数個のトリガ変数です。それらはパラメータとしてスクリプトに渡されます。例:

    export P4LOGINSSO="/path/to/sso-client.sh %user% %serverAddress% %P4PORT%"
    

    %user%はPerforceクライアントユーザです。%serverAddress%はターゲットのPerforceサーバのアドレスです。%P4PORT%はクライアントとサーバ間の仲介者です。

  • サーバ上では、クライアント側スクリプトの出力がサーバ側スクリプトに標準入力として渡されます。トリガテーブルで指定されているサーバ側スクリプトが実行されます。正常に実行されると、サーバは0の終了ステータスを返します。

    プロキシまたはブローカがクライアントおよびサーバ間の媒介として動作する分散構成では、%serverAddress%変数はサーバのアドレスとポートを保持し、%P4PORT%変数は仲介のポートを保持します。この情報を使用して何を行うかはスクリプトによって決定されます。

Example 25. クライアント側とサーバ側でのスクリプトの相互作用

auth-check-ssoトリガは、ユーザがp4 loginを実行すると必ず起動します。サーバ側で実行されるべきスクリプトを指定するには、システム管理者としてトリガテーブルに以下の行を追加するとよいでしょう。

sample13  auth-check-sso  auth  "serverside.sh %user%"

そして、各エンドユーザはクライアント側で以下の環境変数を設定します。

export P4LOGINSSO=/usr/local/bin/clientside.sh %serverAddress%

ユーザがログオンを試みると、P4LOGINSSOスクリプトがユーザのワークステーション上で実行されます。

##!/bin/bash
# clientside.sh - a client-side authentication script
#
# if we use %serverAddress% in the command-line like this:
#    p4 -E P4LOGINSSO=clientside.sh %serverAddress%
# then this script receives the serverAddress as $1, and the user
# can use it for multiple connections to different Perforce servers.
#
# In this example, we simulate a client-side authentication process
# based on whether the user is connecting to the same Perforce Server
# as is already configured in his or her environment.
# (We also output debugging information to a local file.)

input_saddr=$1

env_saddr=`p4 info | grep "Server address" | awk '{printf "%s", $3}'`

if test "$input_saddr" == "$env_saddr"
  then
    # User is connected to the server specified by P4PORT - pass
    echo "sso pass"; echo pass "$input_saddr" >> debug.txt; exit 0
  else
    # User is attempting to connect to another server - fail
    echo "no pass"; echo fail "$input_saddr" >> debug.txt; exit 1
fi

ユーザがP4PORTによって指定されたものと同じPerforceサーバに接続した場合(すなわち、サーバからこのスクリプトへ渡されたサーバアドレスが、p4 infoコマンドのプレーン出力に登場するサーバと一致する場合)、クライアント側の認証は成功します。ユーザが(例えば、異なるPerforceサーバに対しp4 -p host:port loginを実行することにより)他のPerforceサーバに接続した場合、クライアント側の認証は失敗します。

サーバ側スクリプトを以下に示します。

#!/bin/bash
#
# serverside.sh - a server-side authentication script
#

if test $# -eq 0
  then
    echo "No user name passed in.";
    exit 1;
fi

read msg </dev/stdin

if test "$msg" == ""
  then
    echo "1, no stdin"
    exit 1
fi

if test "$msg" == "sso pass"
  then
    exit 0
  else
    exit 1
fi

より現実的な例では、エンドユーザのP4LOGINSSOスクリプトがclientside.shスクリプトを参照し、それが認証サービスにアクセスして何らかのトークンを入手します。次に、クライアント側スクリプトはこのトークンをPerforceサーバのトリガスクリプトに渡し、serverside.shはシングルサインオンサービスを利用してそのトークンを確認します。

上記の例では、clientside.shは、単にユーザがP4PORTによって指定されているのと同じ接続を使用しているかどうかチェックします。そして、clientside.shの出力に"sso pass"という文字列の有無を確認し、文字列が存在していればユーザがログオンを許可されます。

外部認証のためにトリガを起動させる

auth-setタイプのトリガは、ユーザ(標準ユーザまたはサービスユーザ)がp4 passwdコマンドを実行し、かつauth-check(またはservice-check)トリガによって古いパスワードの確認に成功すると、起動します。プロセスは以下のとおりです。

  1. ユーザがp4 passwdを実行します。

  2. Perforceサーバがユーザにパスワードの入力を要求します。

  3. Perforceサーバがauth-checkトリガを実行し、外部認証サービスに照会して古いパスワードを確認します。

  4. auth-checkトリガと関連付けられているスクリプトが実行されます。auth-checkトリガが失敗した場合、プロセスはただちに終了します。ユーザは新しいパスワードを要求されず、auth-setは決して起動しません。

  5. auth-checkトリガが成功した場合、サーバはユーザに新しいパスワードの入力を要求します。

  6. Perforceサーバがauth-setトリガを起動し、新しいパスワードと古いパスワードを改行で区切ったうえで両方をトリガスクリプトに標準入力で供給します。

    Note

    ほとんどの場合、外部認証環境におけるユーザは、Perforceを使用せずに自らのパスワードの設定を続けるでしょう。auth-setトリガタイプは、主に万全を期するために用意されています。

Perforceサーバはユーザの現在のパスワードを検証する必要があるので、auth-setトリガの作成を試みる前に、正しく機能するauth-checkトリガを用意しておく必要があります。

Example 26. ごく簡単な認証設定スクリプトを以下に示します。

#!/bin/bash
# setpass.sh - a trivial authentication-setting script

USERNAME=$1

read OLDPASS
read NEWPASS

echo setpass.sh: $USERNAME attempted to change $OLDPASS to $NEWPASS

ユーザがp4 passwdを実行し、auth-checkトリガによって要求される外部認証に合格すると、このauth-setトリガが起動します。このトリガを使用するには、以下の2行をトリガテーブルに追加します。

sample11  auth-check  auth  "checkpass.sh %user%"
sample12  auth-set    auth  "setpass.sh %user%"

このごく簡単な例では、実際にはパスワードの変更は行われません。単にユーザによって試行された変更の内容を返すにとどまります。

アーカイブに影響するトリガを起動させる

archiveトリガタイプは、+Xファイルタイプ修飾子と組み合わせて使用され、Perforceサーバがファイルをリポジトリ内にアーカイブするのに使用されるメカニズムを置き換える働きをします。それらのファイルはPerforceリポジトリの外部にアーカイブされている内容を保存、管理、生成するのに使用されます。プラットフォーム固有の注意事項については、実行環境を参照してください。

以下の表では、アーカイブトリガの定義に関するフィールドについて説明します。

フィールド

意味

type

archive: +Xファイルタイプ修飾子を含むファイルタイプを持つファイルにユーザがアクセスすると、スクリプトを実行します。スクリプトはアーカイブ内のファイルを読み取り、書き込み、削除することができます。

スクリプトは、1つのファイルが要求されるたびに1度ずつ実行されます。

readの操作に際しては、スクリプトはファイルを標準出力でユーザに提供しなければなりません。writeの操作に際しては、スクリプトはファイルを標準出力で受け取ります。

path

アーカイブ内でアクセス中のファイル名と一致するファイルパターンです。

command

このPerforceサーバ向けトリガは、pathと一致するファイルがアーカイブ内に見つかると起動します。

Perforceサーバアカウントがコマンドを参照して実行できるような方法で、コマンドを指定します。command(普通1回につき1つのスクリプトを呼び出します)は、引用符で囲まれる必要があります。また、commandによって構文上引数として解析できる範囲のあらゆる引数を扱うことができます(適用可能なPerforceトリガ変数を含む)。

トリガスクリプトがディポに保存されている場合、ディポシンタックス内でそのパスをパーセントで囲んで指定する必要があります。例えば、スクリプトがディポに//depot/scripts/myScript.plとして保存されている場合、これに対応してコマンドフィールドで使用される値は"/usr/bin/perl %//depot/scripts/myScript.pl%"となります。詳細については、ディポからトリガを実行するを参照してください。

コマンドが成功した場合、コマンドの標準出力はファイルの内容となります。コマンドが失敗した場合、コマンドの標準出力はトリガ失敗エラーを示すエラーメッセージとしてクライアントに送信されます。

Example 27. アーカイブトリガ

このarchiveトリガは、ユーザが+X(アーカイブ)修飾子を持つファイルにアクセスすると起動します。

#!/bin/sh
# archive.sh - illustrate archive trigger

OP=$1
FILE=$2
REV=$3

if [ "$OP" = read ]
then
    cat ${FILE}${REV}
fi

if [ "$OP" = delete ]
then
    rm ${FILE}${REV}
fi

if [ "$OP" = write ]
then
    # Create new file from user's submission via stdin
    while read LINE; do
        echo ${LINE} >> ${FILE}${REV}
    done
    ls -t ${FILE}* |
    {
        read first; read second;
        cmp -s $first $second
        if [ $? -eq 0 ]
        then
            # Files identical, remove file, replace with symlink.
            rm ${FILE}${REV}
            ln -s $second $first
        fi
    }
fi

このトリガを使用するには、以下の行をトリガテーブルに追加します。

arch  archive  path  "archive.sh %op% %file% %rev%"

ユーザが指定されたpathにおけるタイプ+Xのファイルのサブミット(書き込み)を試みた時点で、現在のリビジョンと前回のリビジョンの間に変更が存在しない場合は、現在のリビジョンは前回のリビジョンを参照するシンボリックリンクに置き換えられます。

トリガスクリプト変数

トリガスクリプト変数を使用して、データをトリガスクリプトに渡すことができます。すべてのデータは文字列として渡されます。こうした文字列を適切に解釈または使用することが、トリガの役割です。

STDINおよびSTDOUTを使用してサーバおよびトリガ間で通信を行うこともできます。詳細については、トリガとサーバ間の通信を参照してください。

maxError...変数は、サーバによるコマンドの完了を妨げる状況(例えばオペレーティングシステムのリソース不足など)を指し示します。また、クライアント側のエラーがいつもサーバに表示されるとは限らず、maxErrorカウントに計上されない場合があることについても注意してください。

terminated変数はコマンドが早期に終了したかどうか示します。また、termType変数は早期終了の理由を示します。

Note

未知の変数の処理方法が変更されています。以前のバージョンでは、未知の変数はトリガの起動時に除外されていました。現在のバージョンでは、未知の変数は除外されません。これによってトリガ引数の配列が維持されるとともに、使用できると想定されているデータが実際にはそうではない場合にトリガ作成者が問題を解決しやすくなっています。

引数

解説

適用できるトリガタイプ

%action%

null、またはチェンジリストかジョブに対して行われたアクションを反映する文字列です。

例えば、"pending change 123 added"か"submitted change 124 deleted"はchangeフォーム上で%action%がとりうる範囲の値であり、また"job000123 created"または"job000123 edited"はjobフォームで%action%がとりうる範囲の値です。

form-commit

%argc%

コマンド引数カウントです。

アーカイブトリガを除くすべてのタイプ

%args%

コマンド引数文字列です。

アーカイブトリガを除くすべてのタイプ

%argsQuoted%

コマンド引数文字列です。この文字列の内容は、複数のコマンド引数をパーセントエンコーディングし、カンマ区切りのリストとして配列したものです。

アーカイブトリガを除くすべてのタイプ

%changelist%%change%

サブミットしようとしているチェンジリストの番号です。短縮形%change%%changelist%と同様に機能します。

change-submitトリガは作業中チェンジリスト番号を渡します。change-commitトリガはコミットされたチェンジリストの番号を受け取ります。

shelve-commitまたはshelve-deleteトリガは当該保留ファイルがあるチェンジリスト番号を受け取ります。


change-submitchange-contentchange-commitfix-addfix-deleteform-commitshelve-commitshelve-delete

%changeroot%

サブミットされたファイルのルートパスです。

change-commit

%client%

トリガを起動させるユーザのクライアントワークスペース名です。

すべて

%clientcwd%

クライアントの現在の作業ディレクトリです。

アーカイブトリガを除くすべてのタイプ

%clienthost%

ユーザのワークステーションのホスト名(プロキシ、ブローカ、レプリカ、エッジサーバを経由して接続する場合も含む)

すべて

%clientip%

ユーザのワークステーションのIPアドレス(プロキシ、ブローカ、レプリカ、エッジサーバを経由して接続する場合も含む)

すべて

%clientprog%

ユーザのクライアントアプリケーション名です。例えば、P4V、P4Winなどとします。

すべて

%clientversion%

ユーザのクライアントアプリケーションのバージョンです。

すべて

%command%

コマンド名です。

アーカイブトリガを除くすべてのタイプ

%file%

ディポのMap:フィールドに基づくアーカイブファイルのパスです。Map:フィールドの値がP4ROOTからの相対パスである場合、%file%はサーバ側のP4ROOTからの相対パスです。Map:フィールドの値が絶対パスである場合、%file%はサーバ側の絶対パスです。

archive

%formfile%

一時フォーム仕様ファイルのパスです。inまたはoutトリガからフォームを編集するには、このファイルを上書きします。タイプsaveおよびdeleteトリガの場合、このファイルは読み取り専用です。


form-commitform-saveform-inform-outform-delete

%formname%

フォーム名です(例えば、ブランチ名やチェンジリスト番号)。


form-commitform-saveform-inform-outform-delete

%formtype%

フォームタイプです(例えば、branchchangeなど)。


form-commitform-saveform-inform-outform-delete

%groups%

ユーザが所属しているグループのリスト(スペース区切り)です。

アーカイブトリガを除くすべてのタイプ

%intermediateService%

ブローカやプロキシを示します。

アーカイブトリガを除くすべてのタイプ

%jobs%

ジョブ番号の文字列です。この変数は、p4 fixコマンドで指定されているジョブ番号1つか、p4 submitまたはp4 changeフォーム中のJobs:フィールドで追加(または削除)されたジョブ番号1つにつき、1つの引数に展開されます。


fix-addfix-delete

%maxErrorSeverity%

emptyerrorwarningのいずれかです。

アーカイブトリガを除くすべてのタイプ

%maxErrorText%

エラー番号とエラーメッセージです。

アーカイブトリガを除くすべてのタイプ

%maxLockTime%

ユーザ指定の値です。許容可能な最長のデータベースロック時間を、ミリ秒単位で指定します。この変数が設定されているということは、ユーザがこの値に関するグループ設定を上書きしたということを意味します。

アーカイブトリガを除くすべてのタイプ

%maxResults%

ユーザ指定の値です。コマンド実行中にバッファするデータ量を指定します。この変数が設定されているということは、ユーザがこの値に関するグループ設定を上書きしたということを意味します。

アーカイブトリガを除くすべてのタイプ

%maxScanRows%

ユーザ指定の値です。一度の操作中にスキャンされる最大行数を指定します。この変数が設定されているということは、ユーザがこの値に関するグループ設定を上書きしたということを意味します。

アーカイブトリガを除くすべてのタイプ

%oldchangelist%

チェンジリストの番号がサブミット時に変更されると、この変数の値は古いチェンジリスト番号になります。

change-commit

%op%

readwritedeleteのいずれかの操作を示します。

archive

%peerhost%

プロキシ、ブローカ、レプリカ、またはエッジサーバを通じてコマンドが送信された場合、プロキシ、ブローカ、レプリカ、エッジサーバのうちいずれかのホスト名を示します。(コマンドが直接送信された場合、%peerhost%%clienthost%と一致します。)

すべて

%peerip%

プロキシ、ブローカ、レプリカ、またはエッジサーバを通じてコマンドが送信された場合、プロキシ、ブローカ、レプリカ、エッジサーバのうちいずれかのIPアドレスを示します。(コマンドが直接送信された場合、%peerip%%clientip%と一致します。)

すべて

%P4PORT%

クライアントが接続するホストのポートです。クライアントが仲介を通じてサーバに接続する場合、この変数は仲介のポート番号を保持します。仲介なしで直接サーバに接続する場合、この変数は%serverAddress%変数と同じ値を保持します。

auth-check-sso(クライアント側スクリプトの場合のみ)

%quote%

二重引用符として使用する文字です。

すべて

%rev%

アーカイブファイルのリビジョンです。

archive

%serverAddress%

PerforceサーバのIPアドレスおよびポート番号です。P4LOGINSSOで指定されているクライアント側スクリプトのコンテキストにおいてのみ渡すことができます。

auth-check-sso(クライアント側スクリプトの場合のみ)

%serverhost%

Perforceサーバのホスト名です。

すべて

%serverpid%

Perforceサーバのserver.idの値です。詳細については、『P4コマンドリファレンス』のp4 serveridを参照してください。

すべて

%serverip%

サーバのIPアドレスです。

すべて

%servername%

PerforceサーバのP4NAMEの値です。

すべて

%serverport%

Perforceサーバのトランスポート、IPアドレス、ポート番号です。形式はprefix:ip_address:portです。

prefixにはssltcp6ssl6のいずれか1つが使用されます。つまり、コマンドp4 -p %serverport%は、サーバ側で使用されている接続タイプにかかわらず、サーバへの接続に使用できます。

すべて

%serverroot%

PerforceサーバのP4ROOTディレクトリです。

すべて

%serverservices%

サーバの役割を指定する文字列です。以下のうちいずれか1つをとります。

  • standard

  • replica

  • broker

  • proxy

  • commit-server

  • edge-server

  • forwarding-replica

  • build-server

  • P4AUTH

  • P4CHANGE

アーカイブトリガを除くすべてのタイプ

%serverVersion%

コマンドが早期に終了した場合、中断したサーバのバージョン文字列を示します。中断の理由は%termType%の値によって示されます。

アーカイブトリガを除くすべてのタイプ

%submitserverid%

分散インストールにおけるchange-*トリガの場合、サブミットを実行していたエッジサーバのserver.idです。詳細については、『P4コマンドリファレンス』のp4 serveridを参照してください。


change-submitchange-contentchange-commit

%terminated%

値が0である場合、コマンドが完了したことを示します。値が1である場合、コマンドが完了しなかったことを示します。

 

%termType%

早期中断の理由を示します。以下のうちいずれか1つをとる可能性があります。

  • 'p4 monitor terminate'

  • client disconnect

  • maxScanRows

  • maxLockTime

  • maxResults

%serverVersion%も参照してください。

アーカイブトリガを除くすべてのタイプ

%triggerMeta_action%

トリガ起動時に実行するコマンドです。トリガ定義の最後のフィールドです。ディポからスクリプトを実行する場合に限って設定してください。

アーカイブトリガを除くすべてのタイプ

%triggerMeta_depotFile%

トリガ定義の第3のフィールドです。このフィールドの意味はトリガタイプによって異なります。change-submitトリガの場合、トリガと一致すべきパスです。form-outトリガの場合、トリガに適用されるべきフォームタイプです。このフィールドの詳細については、該当するトリガタイプの解説を参照してください。

アーカイブトリガを除くすべてのタイプ

%triggerMeta_name%

トリガ定義の第1のフィールド、すなわちトリガ名です。ディポからスクリプトを実行する場合に限って設定してください。

アーカイブトリガを除くすべてのタイプ

%triggerMeta_trigger%

トリガ定義の第2のフィールド、すなわちトリガタイプです。ディポからスクリプトを実行する場合に限って設定してください。

アーカイブトリガを除くすべてのタイプ

%user%

トリガを起動させるユーザのPerforceユーザ名です。

すべて

デーモン

デーモンは、バックグラウンドで定期的に呼び出されるか継続的に実行されるプロセスです。Perforceを使用するデーモンは、通常、必要に応じてサーバメタデータを検証したり、アクションを起こしたりします。

代表的なデーモンのアプリケーションとしては以下のようなものが挙げられます。

  • チェンジレビューデーモン: プロダクションディポにチェンジリストがサブミットされたかどうか確認するため10分ごとに起動し、チェンジリストがサブミットされていた場合、デーモンは、そのチェンジリストに含まれるファイルをサブスクライブしているユーザに対して電子メールを送信します。追跡中のファイルが変更されたことが、メッセージによって通知されます。

  • ジョブデーモン: 作業状態のジョブに関するレポートを毎日の終わりに生成します。レポートでは、カテゴリごとのジョブの数、ジョブごとの重要度などを示します。レポートはすべての関係ユーザに電子メールで送信されます。

  • ウェブデーモン: 特定のディポのサブディレクトリ中のファイルが変更されたかどうか調べます。該当のサブディレクトリに新しいファイルリビジョンが見つかった場合、それを、運用中のウェブページを含むクライアントワークスペースに同期させます。

デーモンは、Perforceメタデータが変更された場合に必然的に発生するほぼすべてのタスクに対して使用できます。トリガが主にサブミットの検証のために使用されるのに対して、デーモンはディポに情報を(つまりサブミットファイルを)書き込むために使用されます。

Perforceのチェンジレビューデーモン

Perforceチェンジレビューデーモン(p4review.py)は、以下のウェブサイトのPerforceパブリックディポから入手できます。

http://public.perforce.com/wiki/P4Review

レビューデーモンの実行に必要なPythonは、http://www.python.orgで入手できます。レビューデーモンの実行前に、そのデーモン本体に含まれる構成説明書を読み、指示にしたがってください。

ユーザはp4 userを呼び出してファイルにサブスクライブします。その際、Email:フィールドに電子メールアドレスを入力し、ユーザにとって関心のあるファイルパターンの番号をReviews:フィールドに入力します。

User:     sarahm
Email:    sarahm@elmco.com
Update:   1997/04/29 11:52:08
Access:   1997/04/29 11:52:08
FullName: Sarah MacLonnogan
Reviews:
        //depot/doc/...
        //depot.../README

チェンジレビューデーモンは、チェンジリストが新しくサブミットされるたびにその中に含まれていたファイルを確認し、そのファイルのいずれかにサブスクライブしているすべてのユーザに対して電子メールを送信して、問題のファイルが変更されたことを知らせます。

特別なパス//depot/jobsReviews:フィールドに入力することにより、ジョブデータが更新されるたびにユーザはPerforceチェンジレビューデーモンから通知メールを受信します。

チェンジレビューデーモンは、以下のスキームを実行します。

  1. p4 counterを使用して、Perforceメタデータ中のカウンタという変数を読み取り、変更します。このデーモンによって使用されるカウンタreviewは、レビュー対象の最新のチェンジリストの番号を保存します。

  2. p4 review -t reviewコマンドを使用して、Perforceディポをポーリングし、まだレビューされていないサブミット済みチェンジリストを探します。

  3. p4 reviewsを使用して、発見された各チェンジリストのレビュー担当者のリストを生成します。

  4. Pythonメールモジュールを使用して、p4 describeチェンジリストの情報を電子メールで各レビュー担当者に通知します。

  5. 上記ステップ1~3が3分ごとに、またはインストール時に設定した間隔で繰り返されます。

ステップ4で使用されるコマンド(p4 describe)は、直接レポートを作成して送信するコマンドです。他のコマンド(p4 reviewp4 reviewsp4 counter)は、ほとんどの場合でレビューデーモンによってのみ実行されるコマンドです。

その他のデーモンを作成する

p4review.py(Perforceのチェンジレビューデーモン参照)を基盤として必要に応じて変更すると、独自のデーモンを作成できます。その一例としては、Perforceジョブ情報を外部バグ追跡システムにアップロードするデーモンなどが考えられます。そのデーモンは、まずp4 reviewコマンドと新しいレビューカウンタを使用して、新しいチェンジリストを作成します。次にp4 fixesを使用して、新しくサブミットされたチェンジリストによって修正されたジョブのリストを取得します。最後にこの情報を外部システムに送信し、一部のジョブの完了を通知します。

作成した独自のデーモンを他のユーザと共有したい場合、デーモンをPerforceパブリックディポにサブミットするとよいでしょう。詳細については、http://public.perforce.comを参照してください。

デーモンによって使用されるコマンド

一部のPerforceコマンドは、ほとんどの場合でレビューデーモンによってのみ実行されます。以下の表では、そのようなコマンドを列挙しています。

コマンド

使用法

p4 review -c change#

change#から最新のサブミット済みチェンジリストまでのすべてのチェンジリストについて、チェンジリストの番号、作成者名、作成者の電子メールアドレスを一覧表示します。

実行するには、少なくともreviewアクセス権限が必要です。

p4 reviews -c change# filespec

指定したチェンジリスト中の指定したファイルまたは任意のファイルのレビューをサブスクライブしているユーザ全員を一覧表示します。

p4 counter name [value]

新しいカウンタを作成するか、既存のカウンタに値を設定するには、少なくともreviewアクセス権限が必要です。カウンタの値を表示するには、少なくともlist権限が必要です。

value引数が指定されていない場合、p4 counternameの値を返します(ただしカウンタが存在しない場合は0を返します)。

value引数が指定されている場合、p4 counternameの値をvalueに指定します。nameが存在しない場合は作成されます。

警告: レビューカウンタjournaljobchangeは、Perforceの内部で使用されています。これらのいずれかをレビュー番号として使用すると、Perforceデータベースが破壊されるおそれがあります。

カウンタは内部的に文字列として表現されます。(リリース2008.1以前では、符号付きintとして保存されていました。)

p4 counters

すべてのカウンタとその値を一覧表示します。

p4 changes -m 1 -s submitted

Perforceサーバに認識されている最大のチェンジリスト番号ではなく、最後にサブミットされたチェンジリストのチェンジリスト番号を、1行で表示します。

デーモンとカウンタ

チェンジレビューデーモンを作成する場合や、サブミット済みチェンジリストを扱う他のデーモンを作成する場合、最新のサブミット済みチェンジリストの番号を確認したほうがよいでしょう。その番号は、p4 changes -m 1 -s submittedコマンドの出力のうち2番目のフィールドで確認できます。

これはp4 counter changeの出力とは異なります。Perforceサーバに認識されている最新のチェンジリスト番号(p4 counter changeの出力)には、ユーザによって作成されながらまだディポにサブミットされてはいない作業中チェンジリストが含まれます。

スクリプトの作成とバッファリング

個々のp4コマンドの出力が、完全にバッファリングされるか(つまり所定のバイト数の生成後にようやく出力がフラッシュされるか)、行ごとにバッファリングされるか(つまりttyのように、改行ごとに1行が送られるか)、あるいはバッファリングされないかということは、使用中のプラットフォームによって異なります。

一般に、ファイルまたはパイプへの標準出力は完全にバッファリングされ、ttyへの標準出力は行ごとにバッファリングされます。使用中のトリガまたはデーモンのために行ごとのバッファリング(またはバッファリングなし)が必要である場合、当該のp4コマンドに-v0デバッグフラグを付けることにより、バッファリングを無効化できます。

パイプを使用してPerforceコマンドで(-v0フラグを付けるにせよ付けないによせよ)標準出力を転送しようとしている場合は、カーネルに起因するバッファリングの障害に直面するおそれがあります。なぜなら-v0フラグは、そのコマンド自体の出力をバッファリングしないようにすることしかできないからです。