これは、CC.NETプリプロセッサが公開する「define」機能と「include」機能の組み合わせに関連する奇妙なものです。CCNet 1.4.4.83を実行ccnet.config
しており、メインの構成ファイルに含まれているサブファイルに格納されている共通の要素ブロックを最大限に活用するようにファイルが構造化および分割されています。また、コアプロジェクト定義を独自のインクルードファイルに分割し、ccnet.config
基本的に一連のインクルードとして残します。
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<!-- Configuration root folder - defined so we can use it as a symbol instead of using slightly confusing relative paths -->
<cb:define ccConfigRootFolder="C:\CruiseControl.NET\Config"/>
<!-- Globals - standard or shared build elements common to all projects -->
<cb:include href="$(ccConfigRootFolder)\Globals\globals.xml" xmlns:cb="urn:ccnet.config.builder"/>
<!-- CruiseControl.NET Configuration - refresh configuration if changed -->
<cb:include href="$(ccConfigRootFolder)\CCNet Configuration\ccnet_configuration.xml" xmlns:cb="urn:ccnet.config.builder"/>
<!-- Project #1 -->
<cb:include href="$(ccConfigRootFolder)\Project1\project1.xml" xmlns:cb="urn:ccnet.config.builder"/>
<!-- Project #2 -->
<cb:include href="$(ccConfigRootFolder)\Project2\project2.xml" xmlns:cb="urn:ccnet.config.builder"/>
</cruisecontrol>
これは扱います-プリプロセッサは<define>
要素を正しく含めて解析しglobals.xml
(そしてそこから含まれる他のファイルも再帰的に解析しglobals.xml
)、後で含まれるプロジェクト(それらの定義された要素への参照を含む)は正しく解析されます。
ccnet.config
ビルドプロセスを壊すミスの可能性を減らすためにさらに改良するために、次のように変更しました。
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<!-- Configuration root folder -->
<cb:define ccConfigRootFolder="C:\CruiseControl.NET\Config"/>
<!-- Project 'include' element definition -->
<cb:define name="ProjectInclude">
<cb:include href="$(ccConfigRootFolder)$(ccIncludePath)" xmlns:cb="urn:ccnet.config.builder"/>
</cb:define>
<!-- Include common gobal elements -->
<cb:ProjectInclude ccIncludePath="\Globals\globals.xml"/>
<!-- Project #1 -->
<cb:ProjectInclude ccIncludePath="\Project1\project1.xml"/>
<!-- Project #2 -->
<cb:ProjectInclude ccIncludePath="\Project2\project2.xml"/>
</cruisecontrol>
ご覧のとおり、「include」定義の共通の繰り返し部分を独自の定義済みブロックに埋め込み、それを使用して、パスをパラメーターとして使用する各インクルードを有効にします。これは、ファイルの将来の修飾子が勝ったという考えです。含まれている新しいプロジェクトライン(プリプロセッサURNなど)で誤って何かを忘れる機会はありません。それらのxmlファイルが存在し、それらへのパスを正しく取得している限り、残りは共通のインクルード定義で処理されます。
唯一の問題は、これが機能しないことです。何らかの理由で、globals.xml
ファイルが適切に解析されていないように見えます(または含まれている可能性もあります)。これは、後に含まれるプロジェクトが要素が定義されていないことを訴えるためです。つまり、グローバルファイルで定義された要素への参照は、プロジェクトがそれらを認識しないため、「登録」されていないように見えます。
globals.xml
ネストされたインクルードをトップレベルから直接取り出してインクルードしようとしましたが、役に立ちませんでした。プロジェクトの最初の厄介な要素参照をコメントアウトすると、Validatorは次の要素について文句を言い、「前処理でXMLの読み込みに失敗しました:不明なシンボルXXXXXへの参照」というメッセージが表示されます。ただし、の本体をに埋め込むと、これは機能しglobals.xml
ます。ccnet.config
奇妙に聞こえるかもしれませんが、プリプロセッサが完全に解析に失敗してglobals.xml
いるように見えますが、プロジェクトファイルをうまくかみ砕いて、グローバル参照が定義されていないために失敗します。
ただし、これが当てはまる場合、バリデーターはサイレントに失敗します。もちろん、プロジェクトXMLを適切に解析できないため、[元の]タブまたは[処理済み]タブにも何も表示されません。CruiseControl.NETサービス自体は、役に立たない例外で開始できません。
サービスを開始できません。System.Runtime.Serialization.SerializationException:タイプ'ThoughtWorks.CruiseControl.Core.Config.Preprocessor.EvaluationException' in Assembly'ThoughtWorks.CruiseControl.Core、Version = 1.4.4.83、Culture = neutral、PublicKeyToken=null'はシリアル化可能としてマークされていません。サーバースタックトレース:System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj、ISurrogateSelector surrogateSelector、StreamingContext context、SerObjectInfoInit serObjectInfoInit、IFormatterConverter converter、ObjectWriter objectWriter)atSystem.Runtime.Serialization.Formatters.Binary.WriteObjectInfo。 Serialize(Object obj、ISurrogateSelector surrogateSelector、StreamingContext context、SerObjectInfoInit serObjectInfoInit、IFormatterConverter converter、
すべてのドキュメントには、これが機能するはずであると記載されており、「define」内で「include」を使用する場合の非互換性や不整合については言及されていません。ですから私は困惑しており、この段階での洞察やアドバイスは高く評価されます。