【发布时间】:2011-02-07 09:56:23
【问题描述】:
这是一个奇怪的问题,它与 CC.NET 预处理器公开的“定义”和“包含”功能的组合有关。我们正在运行 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>
这是一种享受 - 预处理器正确包含并解析 globals.xml 中的 <define> 元素(并递归解析来自 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>
如您所见,我们将“包含”定义中常见的、重复的部分嵌入到它自己定义的块中,然后使用它来影响每个包含,使用路径作为参数 - 想法是未来的修饰符该文件不会有机会意外忘记新包含的项目行中的某些内容(例如预处理器 URN);只要他们的 xml 文件存在并且他们获得了正确的路径,其余的就在公共包含定义中处理。
唯一的问题是这不起作用 - 由于某种原因,看起来globals.xml 文件没有被正确解析(或者甚至可能被包含),因为在它之后包含的项目抱怨没有定义元素;也就是说,对全局文件中定义的元素的引用似乎没有被“注册”,因为项目无法识别它们。
我们尝试从globals.xml 中取出嵌套包含,并将它们直接包含在顶层,但无济于事。注释掉项目中第一个麻烦的元素引用只会导致 Validator 抱怨下一个,并显示消息 “Preprocessing failed loading the XML: Reference to unknown symbol XXXXX”。但是,如果我们将 globals.xml 的主体嵌入到 ccnet.config 中,则可以。虽然听起来很奇怪,但好像预处理器完全无法解析globals.xml,但随后愉快地浏览了项目文件,结果却因为未定义全局引用而失败。
但是,如果是这种情况,Validator 会静默失败。当然,因为它无法正确解析项目 XML,所以我们在“原始”或“已处理”选项卡中也一无所获。 CruiseControl.NET 服务本身无法启动并出现无用的异常:
服务无法启动。 System.Runtime.Serialization.SerializationException: 类型 'ThoughtWorks.CruiseControl.Core.Config.Preprocessor.EvaluationException' 在大会 'ThoughtWorks.CruiseControl.Core, 版本=1.4.4.83,文化=中性, PublicKeyToken=null' 未标记为 可序列化的。服务器堆栈跟踪:在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(对象 obj,ISurrogateSelector 代理选择器,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit, IFormatterConverter 转换器,ObjectWriter objectWriter) 在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(对象 obj,ISurrogateSelector 代理选择器,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit, IFormatterConverter 转换器,ObjectWriter objectWriter) 在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(对象 图,Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Ser...
所有文档都说这应该可以工作,并且在“定义”中使用“包含”时没有提到任何不兼容或不一致。所以我很困惑,在这个阶段,任何见解或建议都会受到高度重视。
【问题讨论】:
标签: include preprocessor cruisecontrol.net