这是一个奇怪的问题,涉及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'定义的公共重复部分,然后使用它来使用路径作为参数来实现每个include - 这个想法是未来的修饰符该文件将没有机会在其新包含的项目行中意外忘记某些内容(例如预处理器URN);只要他们的xml文件存在并且他们获得了正确的路径,其余的就在公共包含定义中处理。
唯一的问题是这不起作用 - 由于某种原因,看起来globals.xml
文件没有被正确解析(或者甚至可能包括在内),因为项目在抱怨没有元素定义;也就是说,对globals文件中定义的元素的引用似乎没有“注册”,因为项目无法识别它们。
我们尝试从globals.xml
中取出嵌套的包含,并将它们直接包含在顶层,但无济于事。在项目中注释掉第一个麻烦的元素引用只会导致Validator抱怨下一个,消息“预处理加载XML失败:引用未知符号XXXXX”。但是,如果我们将globals.xml
的主体嵌入ccnet.config
,则可行。虽然听起来很奇怪,但好像预处理器完全无法解析globals.xml
但是很高兴地咀嚼项目文件,然后失败因为没有定义全局引用。
然而,如果是这种情况,验证器会以静默方式失败。当然,因为它无法正确解析项目XML,我们也无法在“原始”或“已处理”选项卡中获得任何内容。 CruiseControl.NET服务本身无法以无益的异常开始:
无法启动服务。 System.Runtime.Serialization.SerializationException: 类型 'ThoughtWorks.CruiseControl.Core.Config.Preprocessor.EvaluationException' 在大会 “ThoughtWorks.CruiseControl.Core, 版本= 1.4.4.83,文化=中立, PublicKeyToken = null'未标记为 序列化。服务器堆栈跟踪:at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(对象 obj,ISurrogateSelector surrogateSelector,StreamingContext context,SerObjectInfoInit serObjectInfoInit,IFormatterConverter 转换器,ObjectWriter objectWriter) 在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(对象 obj,ISurrogateSelector surrogateSelector,StreamingContext context,SerObjectInfoInit serObjectInfoInit,IFormatterConverter 转换器,ObjectWriter objectWriter) 在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(对象 graph,Header [] inHeaders, __BinaryWriter serWriter,Boolean fCheck)at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Ser ...
所有文档都说这应该有效,并且在'define'中使用'include'时没有提及任何不兼容或不一致。所以我很难过,在这个阶段,任何见解或建议都会受到高度重视。
答案 0 :(得分:1)
我们正在为1.5版本解决此问题(希望在本月结束) http://jira.public.thoughtworks.org/browse/CCNET-1865
亲切的问候 鲁本威廉姆斯答案 1 :(得分:0)
CCnet 1.5 Final已经发布,所以这给你测试它的借口:-) 如果问题仍然存在,您也可以通过ccnet列表与我联系。 http://groups.google.com.ag/group/ccnet-user或 http://groups.google.com.ag/group/ccnet-devel