Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

スタジオのソース・コントロール・フックの使用法

Caché コードをソース・コントロールに配置するには、スタジオをサードパーティのソース・コントロール・システムに接続する必要があります。この付録では、その方法を説明します。以下のトピックについて説明します。

概要

Caché 開発プロジェクトをソース・コントロールに配置するには、以下を実行します。

  • コード・ユニットを XML ファイルとして表し、ドキュメント・システムに書き込みます。Caché では、クラス定義、ルーチン、または CSP ファイルは、ドキュメントと呼ばれる 1 つのユニットと見なされます。

  • XML ファイルをソース・コントロールに配置します。

  • XML ファイルが Caché ドキュメントと互いに同期していることを確認し、両方が適切な読み取り/書き込み状態にあることを確認してください。

  • スタジオ内からソース・コントロールの機能を実行できることを確認します。

  • ドキュメントの状態 (ドキュメントがチェック・アウトされたかどうか、また、チェック・アウトされた場合はどのユーザがチェックアウトしたか) について、スタジオとソース・コントロール・システムが常に同じ情報を共有していることを確認します。

Caché ドキュメント

Caché ドキュメントとは、クラス定義、ルーチン、インクルード・ファイル、または CSP ファイルです。Caché では、最後にコンパイルされてから変更があったかどうかなど、各 Caché ドキュメントに関する情報が記録されます。ソース・コントロール・システムは、各 Caché ドキュメントを個別のユニットとして扱います。ドキュメント・ウィンドウのアイコンを使用すると、ドキュメントの状態が表示されます。

Caché では、一度に 1 つのネームスペース内で作業します。ソース・コントロール・システムでも同様です。

ドキュメントとファイルを管理するツール

Caché では、Caché ドキュメントと外部ファイルを管理するために、以下のツールが用意されています。

  • %Studio.Extension.BaseOpens in a new tab クラスと %Studio.SourceControl.BaseOpens in a new tab クラスは、基本的なドキュメント管理のためのメソッドを提供します。これらのクラスのいずれかを拡張して Caché ドキュメントで機能するメニュー項目を追加できます。これらのクラスの詳細は、このドキュメントの “ソース・コントロール・クラスの作成と有効化” のセクションを参照してください。

  • $system.OBJ.Export 関数は、Caché ドキュメントを外部のドキュメント・システムにある XML ファイルにエクスポートします。この XML ファイルには、Caché ドキュメントの再構築に必要な情報がすべて含まれています。例えば、クラス・ドキュメントの場合、対応する XML ファイルは、すべてのコード、プロパティ、コメントなどを含むクラス定義全体のテキスト表示です。

  • $system.OBJ.Load 関数は、外部 XML ファイルをロードし、対応する Caché ドキュメントが存在する場合はそれを上書きします。

  • %RoutineMgr.TS クラス・メソッドは、Caché ドキュメントのタイムスタンプを返します。さらに、このメソッドは、2 番目の引数として Caché ドキュメントのコンパイル時間を参照として返します。

内部名と外部名をマップする方法の指定

各ドキュメントには 2 つの名前があります。

  • 内部名は、スタジオの [開く] ダイアログ・ボックスで使用する名前です。

  • 外部名は、パスを含む、完全な外部ファイル名です。サポートされる Caché プラットフォーム間での相違点により、意味のある既定を提供できません。

内部名と外部名の間に双方向のマッピングを設定します。実際には、これを実行する方法の決定は、ソース・コントロール・インタフェースを作成するうえで最も難しい部分です。このマッピングはユーザ固有のものであり、注意深く考慮する必要があります。

ソース・コントロール・ツールで同様の項目をグループ化できます。例えば、サンプルでは以下のディレクトリ構造が使用されます。

  • クラス・ファイルは、クラスのパッケージ階層に対応するサブディレクトリを含む cls サブディレクトリ内にあります。

  • .INT ルーチンは int サブディレクトリ内にあります。

  • .MAC ルーチンは mac サブディレクトリ内にあります。

  • CSP ファイルは、CSP ファイルのパッケージ階層に対応するサブディレクトリを含む csp サブディレクトリ内にあります。

例えば、クラス MyApp.Addresses.HomeAddress の外部名は、C:\sources\cls\MyApp\Addresses\HomeAddress.xml です。

この方法では、多数のルーチンを使用している場合に問題が発生する可能性があります。そのような場合は、機能別など、何らかの方法でルーチンをサブディレクトリにグループ化できます。

ソース・コントロール・クラスの作成と有効化

このセクションでは、ソース・コントロール・クラスを作成して有効化するための基本的な要件について説明します。

スタジオの拡張

Caché では、スタジオへのメニュー項目の追加に使用できるクラスが提供されます。スタジオにソース・コントロール・メニューを追加するには、%Studio.Extension.BaseOpens in a new tab または %Studio.SourceControl.BaseOpens in a new tab を使用します。

Note:

スタジオに追加できるメニューの数を制限します。それぞれ 19 のメニュー項目を持つメニューを最大 2 つ追加できます。

%Studio.Extension.BaseOpens in a new tab クラスでは、以下のメソッドが提供されます。これらのメソッドではすべて Caché ドキュメントの内部名が使用されます。

  • 空の Login メソッドと Logout メソッド。必要に応じて実装できます。変数 $username によって、現在のユーザが記録されます(Login メソッドでは、Username 引数が後方互換性のために提供されているので、代わりに、変数 $username の使用をお勧めします)。

  • 指定した Caché ドキュメントの状態を示す基本的なメソッド : GetStatus および IsInSourceControl。必要に応じて、これらのメソッドを実装します。

  • コールバック・メソッド。スタジオのユーザが Caché ドキュメントでアクションを実行するときに実行されます。これらのメソッドには、OnBeforeLoadOnAfterLoadOnBeforeCompileOnAfterCompileItemIconState などがあります。

Note:

スタジオのクラス・コンパイルでは、複数のプロセスを使用できます。したがって、情報を MenuItem から OnBeforeCompile に渡すために %Studio.Extension.BaseOpens in a new tab のプロパティを使用しないでください。その代わりに、一時グローバルを使用してください。

%Studio.SourceControl.BaseOpens in a new tab クラスは、上記のクラスのサブクラスです。%Studio.SourceControl.BaseOpens in a new tab では、以下の追加要素が提供されます。

  • Menu という名前の XDATA ブロック。スタジオの追加メニュー [ソース・コントロール] を定義します。既定では、このメニューには、メニュー項目 [チェック・イン][チェック・アウト][チェックアウトを元に戻す][最新を取得]、および [ソース・コントロールに追加] が含まれています。また、この XDATA ブロックは、スタジオのコンテキスト・メニューの追加メニュー項目も定義します。

    これらすべてのメニュー項目は、このクラスで定義されているメソッドも呼び出します。

  • CheckInCheckOutUndoCheckOutGetLatest、および AddToSourceControl という名前のメソッドは、既定では何も実行しません。

スタジオを拡張するには、これらのクラスのいずれかを拡張する新しいクラスを定義します。“ソース・コントロール・クラスの有効化” で説明するように、管理ポータルには、指定したネームスペースで現在アクティブな拡張クラスを示す方法が用意されています。指定したネームスペースで拡張クラスがアクティブな場合、および、そのクラスが XDATA メニュー・ブロックを定義する場合は、これらのメニュー項目がスタジオに追加されます。

ソース・コントロール・クラスの作成

ソース・コントロール・クラスを作成するには、以下を実行します。

  1. %Studio.Extension.BaseOpens in a new tab または %Studio.SourceControl.BaseOpens in a new tab のサブクラスを作成します。

  2. %Studio.Extension.BaseOpens in a new tab から開始する場合、サブクラスで Menu という名前の XDATA ブロックを作成します  (これを開始するには、%Studio.SourceControl.BaseOpens in a new tab からコピーして貼り付けます)。

  3. 必要に応じて、このクラスにメソッド AddToSourceControlCheckInCheckOut などを実装します。これらのメソッドは、通常、少なくとも以下を実行します。

    • 必要に応じて、Caché ドキュメントを XML からインポート、または XML にエクスポートします。

    • XML ファイルで機能するように、ソース・コントロール・ソフトウェアの適切な関数またはメソッドを呼び出します。

    • 指定したファイルの状態について Caché の内部情報を更新します。

    • Caché ドキュメントが編集可能であるかどうかを制御します。

    詳細は、ソース・コントロール・システムにより異なります。サンプルでは、いくつかの有用な方法が示されています。詳細は、このドキュメントの “サンプルのソース・コントロール・クラス” のセクションを参照してください。

  4. ソース・コントロール・クラスの GetStatus メソッドを実装します。これは必須です。既定の実装が適切でない場合は、IsInSourceControl メソッドの実装も必要な場合があります。

ソース・コントロール・クラスの有効化

指定したネームスペースに対してソース・コントロール・クラスを有効にするには、以下を実行します。

  1. 拡張クラスが存在する場合、管理ポータルを使用して、指定したネームスペースでスタジオが使用する拡張クラスを指定します。使用するクラスを指定するには、以下の操作を実行します。

    1. 管理ポータルの システム, 構成, ソースコントロール設定 ページに移動します。([システム管理]→[構成]→[追加設定]→[ソースコントロール] を選択します。)

    2. ページの左側で、この設定に適用するネームスペースを選択します。

    3. 使用する拡張クラスの名前を選択するか、[NONE] を選択して、[OK] を選択します。

      このリストには %Studio.Extension.BaseOpens in a new tab のコンパイルされたすべてのサブクラスが含まれます。

  2. スタジオが現在開いている場合は、いったん閉じてから再び開きます。または、別のネームスペースに切り替えてから元に切り替え直します。

ソース・コントロール・システムへのアクセス

ソース・コントロール・システムの API には、ファイルのチェック・アウトなど、ソース・コントロールの機能を実行するためのメソッドまたは関数が用意されています。ソース・コントロール・クラスは、この API の適切な呼び出しを行う必要があります。また、Caché サーバは、API 自体を定義する共有ライブラリまたは他のファイルの場所を特定する必要があります。

ソース・コントロール・システムで COM インタフェースを使用できる場合、そのインタフェースでメソッドの呼び出しに使用できる Caché ラッパ・クラスのセットを生成できます。このためには、スタジオで Caché アクティベート・ウィザードを使用します。インタフェースと、クラスを格納するパッケージの名前を指定すると、ウィザードによってクラスが生成されます。詳細は、"Caché ActiveX ゲートウェイの使用法" を参照してください。

また、Caché が Caché サーバ上でソース・コントロール・コマンドを実行することにも注意する必要があります。つまり、XML ファイルは Caché サーバ上にあり、ファイル・マッピングが、そのサーバ上で使用するオペレーティング・システムで機能する必要があります。

例 1

以下のフラグメントでは、Caché アクティベート・ウィザードを使用して、VSS の API 用のラッパ・メソッドを生成しました。次に、ソース・コントロール・メソッド内に以下のようなコードを含めることができます。

 do ..VSSFile.CheckIn(..VSSFile.LocalSpec,Description)

詳細は、ソース・コントロール・ソフトウェア、その API、および要件によって異なります。

例 2

以下のフラグメントでは、Windows コマンド行インタフェースを使用してファイルをチェック・アウトしています。この例では、ソース・コントロール・システムは Perforce です。

/// Check this routine/class/csp file out of source control.
Method CheckOut(IntName As %String, Description As %String) As %Status
{
  Set file=..ExternalName(IntName)
  If file="" Quit $$$OK
  //...
 Set cmd="p4 edit """_file_""""


  #; execute the actual command
  Set sc=..RunCmd(cmd)
  If $$$ISERR(sc) Quit sc

  #; If the file still does not exist or
  #; if it is not writable then checkout failed
  If '##class(%File).Exists(file)||(##class(%File).ReadOnly(file)) {
    Quit $$$ERROR($$$GeneralError,
                  "Failure: '"_IntName_"' not writeable in file sys")
  }

  #; make sure we have latest version
  Set sc=..OnBeforeLoad(IntName)
  If $$$ISERR(sc) Quit sc

  //...
  Quit sc
}

この例では、RunCmd は、指定したコマンドを実行して一部の汎用エラーのチェックを行う別のメソッドです。(RunCmd は、$ZF(-1) インタフェースから OS コマンドを発行します。)

また、この CheckOut メソッドは、Caché ドキュメントと外部 XML ドキュメントを同期させる OnBeforeLoad メソッドを呼び出します。

サンプルのソース・コントロール・クラス

SAMPLES ネームスペースには、サンプルのソース・コントロール・クラス Studio.SourceControl.ExampleOpens in a new tab が用意されています。このセクションでは、このサンプルが機能するしくみを示します。以下の項目について説明します。

Note:

SAMPLES ネームスペースのクラスは、ここに示す例とわずかに異なる場合があります。特に、このドキュメントでは見やすくするために改行の一部が調整されています。

はじめに

Studio.SourceControl.ExampleOpens in a new tab は、ソース・コントロール・システムの呼び出しを実行しない部分的な例です。このクラスは、ソース・コントロール・システムで使用する外部 XML ファイルを保持するだけです。このように簡略化されていますが、この例では以下のすべてが示されています。

  • 各 Caché ドキュメントと対応する外部ファイルのリレーションシップの確立と維持

  • 各ファイルの状態により Caché を最新の状態に保持

  • 各 Caché ドキュメントの読み取り/書き込み状態の適切な制御

  • ファイルをチェック・インおよびチェック・アウトするためのメソッドの定義

この例では、外部ファイルの読み取り/書き込み状態は変更されません。ただし、状態を変更する場合は、ソース・コントロール・システムがそれを実行します。また、サンプルは、Check In メソッドと Check Out メソッドのみを実装します。

SAMPLES ネームスペースでこの例を試行するには、以下の手順を実行します。

  1. 前述の “ソース・コントロール・クラスの有効化” で説明したように、管理ポータルを使用して、このソース・コントロール・クラス (Studio.SourceControl.ExampleOpens in a new tab) を有効にします。

  2. スタジオの [ワークスペース] ウィンドウで、Caché ドキュメントをダブルクリックします。[出力] ウィンドウで以下のようなメッセージを確認します。

    File C:\sources\cls\User\LotteryUser.xml not found, skipping import
    
  3. ドキュメントを編集します (コメントを追加するなど)。

  4. [ファイル]→[保存] を選択します。[出力] ウィンドウに以下のようなメッセージが表示されます。

    Exported 'User.LotteryActivity.CLS' to file
    'C:\sources\cls\User\LotteryActivity.xml'
    

    この手順で、Caché ドキュメントがソース・コントロール・システムに暗黙的に追加されました。

  5. 別の編集を行います。スタジオから、ファイルをチェック・アウトするかどうかを尋ねるダイアログ・ボックスが表示されます。[いいえ] を選択します。Caché ドキュメントが読み取り専用のままであることを確認します。

  6. [ソースコントロール]→[チェックアウト] を選択して、[はい] を選択します。これで、Caché ドキュメントを編集できるようになります。

  7. [ソースコントロール]→[チェックイン] を選択して、[はい] を選択します。これで、Caché ドキュメントが再び読み取り専用になります。

[ソース・コントロール] メニューのその他のメニュー項目では何も実行されません。サンプルに実装したのは Check In メソッドと Check Out メソッドのみだからです。

グローバル

Studio.SourceControl.ExampleOpens in a new tab サンプルでは、グローバルを使用して必要な永続情報が記録されます。このクラスのメソッドでは、以下の構造を持つ ^MySourceControl グローバルが保持され、使用されます。

ノード コンテンツ
^MySourceControl("base") XML ファイルを格納するディレクトリの絶対パス。既定は C:\sources\ です。
^MySourceControl(0,IntName)、ここでIntName は Caché ファイルの内部名 対応する外部ファイルが最後に変更された日付と時刻。
^MySourceControl(1,IntName) この Caché ドキュメントが最後に変更された日付と時刻。
^MySourceControl(2,IntName) 存在する場合、この Caché ドキュメントをチェック・アウトしたユーザの名前。

このグローバルはサンプルであり、このクラスでのみ使用されます。

外部名の指定

Studio.SourceControl.ExampleOpens in a new tab クラスを有効にした場合、このクラスでは、ロードまたは作成する Caché ドキュメントに対応する外部 XML ファイルが保持されます。“内部名と外部名をマップする方法の指定” で説明したように、既定では、これらのファイルはディレクトリ C:\sources\ に書き込まれます。例えば、クラス MyApp.Addresses.HomeAddress の外部名は、C:\sources\cls\MyApp\Addresses\HomeAddress.xml です。

このサンプルでは、ExternalName メソッドによって Caché ドキュメントの外部ファイル名が指定されます。このメソッドは、以下のとおりです。

Method ExternalName(IntName As %String) As %String
{
 Set name=$piece(IntName,".",1,$length(IntName,".")-1)
 Set ext=$zconvert($piece(IntName,".",$length(IntName,".")),"l")
 If name="" Quit ""
 Set filename=ext_"\"_$translate(name,".","\")_".xml"
 Quit $get(^MySourceControl("base"),"C:\sources\")_filename
}

当然ながら、このサンプルは Windows にのみ適しています。このメソッドの実装は、UNIX® や OpenVMS では異なる内容にする必要があります。

Caché ドキュメントと外部ファイルの同期化

2 つのメソッドで、Caché ドキュメントと対応する XML ファイルが互いに同期していることが確認されます。

  • スタジオは、Caché ドキュメントをワーク・スペースにロードする直前に OnBeforeLoad メソッドを呼び出します。

  • スタジオは、Caché ドキュメントの保存直後に OnAfterSave メソッドを呼び出します。

このサンプルでは、OnBeforeLoad メソッドは、以下のとおりです。

Method OnBeforeLoad(IntName As %String) As %Status
{
 Set filename=..ExternalName(IntName)
 If filename="" Quit $$$OK

 #; If no file then skip the import
 If '##class(%File).Exists(filename) {
     Write !,"File ",filename," not found, skipping import"
     Quit $$$OK
 }

 #; If the timestamp on the file is the same as the last time
 #; it was imported, then do nothing
 If ##class(%File).GetFileDateModified(filename)=
                   $get(^MySourceControl(0,IntName)) {
     Quit $$$OK
 }

 #; Call the function to do the load
 Set sc=$system.OBJ.Load(filename,"-l-d")
 If $$$ISOK(sc) {
 Write !,"Imported '",IntName,"' from file '",filename,"'"
 Set ^MySourceControl(0,IntName)=##class(%File).GetFileDateModified(filename)
 Set ^MySourceControl(1,IntName)=##class(%RoutineMgr).TS(IntName)
 } Else {
 Do $SYSTEM.Status.DecomposeStatus(sc,.errors,"d")
 }
 Quit sc
}

メモ :

  • このメソッドでは、外部ファイルが存在するかどうかが確認されます。外部ファイルが存在する場合、メソッドは、ファイルのタイム・スタンプを Caché ドキュメントのタイム・スタンプと比較します。外部ファイルが Caché ドキュメントより新しい場合、メソッドは外部ファイルをロードします。

    厳密には、タイム・スタンプを確認する必要はありません。このメソッドは外部ドキュメントを毎回ロードできるからです。パフォーマンスの向上につながるため、チェックが実行されます。

  • このメソッドによって、^MySourceControl グローバルの関連ノードが設定されます。

サンプルでわかるように、OnAfterSave メソッドと類似しています。

Note:

前述のように、スタジオでこれらのメソッドが自動的に呼び出されるだけではなく、Caché ドキュメントと外部ドキュメントが同期していることを確認する必要があるときはいつでもこれらのメソッドを呼び出します。

Caché ドキュメントの状態の制御

ソース・コントロール・クラスの GetStatus メソッドは、指定した Caché ドキュメントの状態に関する情報を返します。このメソッドには、以下のシグニチャがあります。

Method GetStatus(IntName As %String,
                 ByRef IsInSourceControl As %Boolean,
                 ByRef Editable As %Boolean,
                 ByRef IsCheckedOut As %Boolean,
                 ByRef UserCheckedOut As %String) As %Status

スタジオは、Caché ドキュメントで作業するさまざまな場合に、このメソッドを呼び出します。例えば、このメソッドを使用して、Caché ドキュメントが読み取り専用であるかどうかを判断します。ソース・コントロール・クラスを実装した場合は、このメソッドを適切に実装する必要があります。

このサンプルでは、このメソッドは以下のように実装されます。

Method GetStatus(IntName As %String,
                 ByRef IsInSourceControl As %Boolean,
                 ByRef Editable As %Boolean,
                 ByRef IsCheckedOut As %Boolean,
                 ByRef UserCheckedOut As %String) As %Status
{
 Set Editable=0,IsCheckedOut=0,UserCheckedOut=""
 Set filename=..ExternalName(IntName)
 Set IsInSourceControl=(filename'=""&&(##class(%document).Exists(filename)))
 If 'IsInSourceControl Set Editable=1 Quit $$$OK

 If $data(^MySourceControl(2,IntName))
 {Set IsCheckedOut=1
 Set UserCheckedOut=$listget(^MySourceControl(2,IntName))}

 If IsCheckedOut,UserCheckedOut=..Username Set Editable=1
 Quit ..OnBeforeLoad(IntName)
}

このメソッドは、次のように動作します。

  1. 最初に、メソッドは、参照によって返す引数すべてを初期化します。

  2. 次に、メソッドは外部ドキュメントが存在するかどうかを確認します。存在しない場合、Caché ドキュメントは編集可能です。

  3. 次に、メソッドは、このドキュメントをチェック・アウトしたユーザがいるかどうかを確認するために、^MySourceControl グローバルを確認します。チェック・アウトしたユーザがいる場合、そのユーザが現在のユーザであれば、このドキュメントは編集可能です。別のユーザがチェック・アウトした場合、現在のユーザはこのドキュメントを編集できません。

  4. 最後に、このメソッドは、このドキュメントで前述した OnBeforeLoad メソッドを呼び出します。この手順により、Caché ドキュメントと外部 XML ファイルが同期していること、および ^MySourceControl グローバルの関連ノードが設定されていることが確認されます。

ソース・コントロール・アクション

このサンプルでは、最も基本的な 2 つのソース・アクションであるチェック・インとチェック・アウトのためのメソッドを実装します。

CheckIn メソッドは、以下のとおりです。

Method CheckIn(IntName As %String, Description As %String) As %Status
{
 #; See if we have it checked out
 If '$data(^MySourceControl(2,IntName)) {
   Quit $$$ERROR($$$GeneralError,"You cannot check in an item
                                  you have not checked out")
 }
 If $listget(^MySourceControl(2,IntName))'=..Username {
   Quit $$$ERROR($$$GeneralError,"User '"_
         $listget(^MySourceControl(2,IntName))_"'has this item checked out")
}

 #; Write out the latest version
 Set sc=..OnAfterSave(IntName)
 If $$$ISERR(sc) Quit sc

 #; Remove the global to show that we have checked it in
 Kill ^MySourceControl(2,IntName)
 Quit $$$OK
}

メモ :

  • このメソッドでは、^MySourceControl グローバルを使用して、現在のユーザがこの Caché ドキュメントに実際にチェック・インできるかどうかを確認します。

  • ユーザがドキュメントをチェック・アウトできる場合、メソッドは以下を実行します。

    • メソッドは、OnAfterSave を呼び出して、Caché ドキュメントと外部ドキュメントが同期していることを確認します。

    • メソッドは、^MySourceControl グローバルの該当するノードを削除して、現在ドキュメントがチェック・インされていることを示します。

CheckOut メソッドも同様です。

これらのメソッドは、サードパーティのソース・コントロール・システムに対する適切な呼び出しを含めるために拡張できます。

その他の詳細

既定では、メソッド IsInSourceControlGetStatus メソッドを呼び出し、そこから必要な情報を取得します。

サンプルでは、メソッド IsInSourceControl は、すべての内部名に対して True を返します。すべてのドキュメントがソース・コントロールにあるという前提を思い出してください。

コンパイルでストレージ情報が更新される可能性があるため、コンパイル時にクラス定義が変更される場合があります。このため、サンプルは OnAfterCompile メソッドを実装します。このメソッドは、OnAfterSave メソッドが提供するロジックと同じロジックを必要とするため、OnAfterSave メソッドを呼び出します。特に、OnAfterCompile メソッドでは、Caché ドキュメントが変更されているかどうかを確認する必要があり、変更されている場合は、XML ファイルを再び保存します。

各プロセスが同じスレッドで実行されるとは限らないため、プロセス・プライベート・グローバルをソース・コントロール・フック内で使用することはお勧めしません。 詳細は、"Caché リリース・ノートおよびアップグレード・チェックリスト・アーカイブ" の “Cache 2012.1” の章を参照してください。

FeedbackOpens in a new tab