1

这是一个与 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>

这是一种享受 - 预处理器正确地包含并解析其中的<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>

正如你所看到的,我们在它自己定义的块中嵌入了“包含”定义的常见、重复的部分,然后使用它来影响每个包含,使用路径作为参数——这个想法是文件的未来修饰符赢了'没有机会意外忘记他们新包含的项目行中的某些内容(例如预处理器 URN);只要他们的 xml 文件存在并且他们获得了正确的路径,其余的就在公共包含定义中处理。

唯一的问题是这不起作用——由于某种原因,看起来globals.xml文件没有被正确解析(或者甚至可能被包含),因为在它抱怨没有定义元素之后包含的项目;也就是说,对全局文件中定义的元素的引用似乎没有被“注册”,因为项目无法识别它们。

我们尝试从globals.xml顶层中取出嵌套包含并直接将它们包含在内,但无济于事。注释掉项目中第一个麻烦的元素引用只会导致 Validator 抱怨下一个,并显示消息"Preprocessing failed loading the XML: Reference to unknown symbol XXXXX"。但是,如果我们将主体嵌入globals.xmlinto ccnet.config,则可以。虽然听起来很奇怪,但就好像预处理器完全无法解析globals.xml,但随后愉快地浏览了项目文件,只是因为未定义全局引用而失败。

但是,如果是这种情况,验证器会静默失败。当然,因为它无法正确解析项目 XML,所以我们在“原始”或“已处理”选项卡中也一无所获。CruiseControl.NET 服务本身无法以无用的异常启动:

无法启动服务。System.Runtime.Serialization.SerializationException:在程序集“ThoughtWorks.CruiseControl.Core,版本=1.4.4.83,文化=中性,PublicKeyToken=null”中键入“ThoughtWorks.CruiseControl.Core.Config.Preprocessor.EvaluationException”未标记为可序列化. 服务器堆栈跟踪:在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo 的 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)。序列化(对象 obj,ISurrogateSelector surrogateSelector,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit,IFormatterConverter 转换器,

所有文档都说这应该有效,并且在“定义”中使用“包含”时没有提及任何不兼容或不一致。所以我很难过,在这个阶段,任何见解或建议都会受到高度重视。

4

2 回答 2

1

我们正在为 1.5 版本解决这个问题(希望本月结束) http://jira.public.thoughtworks.org/browse/CCNET-1865

亲切的问候鲁本威廉斯

于 2010-04-13T14:23:14.183 回答
0

CCnet 1.5 Final 已经发布,所以这给了你测试它的借口:-) 如果问题仍然存在,你也可以通过 ccnet 列表与我联系。 http://groups.google.com.ag/group/ccnet-userhttp://groups.google.com.ag/group/ccnet-devel

于 2010-05-03T06:39:50.407 回答