CI学习 CCNET Config 第一天
CCNet的整体结构就是一个Xml文档,根元素就是cruisecontrol,具体的代码块如下所示:
- <cruisecontrol xmlns:cb="urn:ccnet.config.builder">
- <project name="P1">
- <other settings />
- </project>
- <project name="P2">
- <other settings />
- </project>
- </cruisecontrol>
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project name="P1">
<other settings />
</project>
<project name="P2">
<other settings />
</project>
</cruisecontrol>
其中,命名空间标定了CCNet里面的预处理过程(Preprocessor)。
一、预处理:Preprocessor
预处理里面包含三个主要元素:define、include和scope,define用于定义以后扩展的常量、include用于包含其他文件的类容,而scope用于封装现存的常量的值。
1、define元素
define元素可以用来定义一个预处理(Preprocessor)常量。如下所示:
- <cb:define foo="bar" />
<cb:define foo="bar" />
也可以在一行中定义多个常量:
- <cb:define a="1" b="2" c="3"/>
<cb:define a="1" b="2" c="3"/>
还可以定义一个xml段:
- <cb:define name="baz">
- <some_element>
- <some_inner_element/>
- </some_element>
- </cb:define>
<cb:define name="baz">
<some_element>
<some_inner_element/>
</some_element>
</cb:define>
任何有效的xml代码元素都可以包含其中,包括元素、属性、文本节点和注释等。
有两种方式来使用定义的常量:文本引用和xml引用
1)、文本引用的方式如下:$(const_name)
如果常量未定义,系统将搜索系统变量来替换;如果系统变量也不存在,将引发错误。
- <pre><code class="xml syntaxhl"><span class="CodeRay"><span class="tag"><cb:define</span> <span class="attribute-name">foo</span>=<span class="string"><span class="delimiter">"</span><span class="content">bar</span><span class="delimiter">"</span></span><span class="tag">/></span></span></code>
<pre><code class="xml syntaxhl"><span class="CodeRay"><span class="tag"><cb:define</span> <span class="attribute-name">foo</span>=<span class="string"><span class="delimiter">"</span><span class="content">bar</span><span class="delimiter">"</span></span><span class="tag">/></span></span></code>
<somexml attr1="$(foo)"/>
<somexml>$(foo)</somexml>
<env dir="$(PATH)"/>
2)、xml引用的方式如下:
如果常量未定义,系统将搜索系统变量来替换;如果系统变量也不存在,将引发错误。
- <cb:define foo="bar"/>
- <sample>
- <cb:foo/>
- </sample>
<cb:define foo="bar"/> <sample> <cb:foo/> </sample>
其效果是直接替换被引用的值,上面结果如下:
- <sample>
- bar
- </sample>
<sample> bar </sample>
3)、常量的嵌套以及参数
常量引用可以嵌套使用,如下所示:
- <cb:define alpha="alphaval"/>
- <cb:define zed="zedval/$(alpha)"/>
- <z>$(zed)</z>
<cb:define alpha="alphaval"/> <cb:define zed="zedval/$(alpha)"/> <z>$(zed)</z>
在高层次的嵌套时,在cb:varname这种语法中,常量值是可以传递到调用的元素中去的,如下面的例子:
- <cb:define name="beta">
- <hello>
- <cb:gamma/>
- <hi attr1="$(delta)"/>
- </hello>
- </cb:define>
<cb:define name="beta">
<hello>
<cb:gamma/>
<hi attr1="$(delta)"/>
</hello>
</cb:define>
此时的gamma和delta都还没有定义
- <cb:beta delta="deltaval">
- <cb:define name="gamma">
- <gamma_element>hi</gamma_element>
- </cb:define>
- </cb:beta>
<cb:beta delta="deltaval">
<cb:define name="gamma">
<gamma_element>hi</gamma_element>
</cb:define>
</cb:beta>
在定义了如下xml段之后,gamma就可以正常被替换了,而且上面没有定义的delta常量,也会通过cb:deta定义的delta常量所替换。最终结果如下:
- <hello>
- <gamma_element>hi</gamma_element>
- <hi attr1="deltaval" />
- </hello>
<hello> <gamma_element>hi</gamma_element> <hi attr1="deltaval" /> </hello>
2、Scope元素
Scope用于控制预处理定义中的范围,在同一个范围里面不可以定义相同的常量,但是在嵌套的范围里面,可以覆盖外层定义的常量,这一点和程序里面的代码段很像。
如下定义:
- <cb:scope a="a_val" b="b_val">
- <test attr="$(a)" attr2="$(b)"/>
- <cb:scope a="a_val_redefined">
- <test attr="$(a)" attr2="$(b)"/>
- </cb:scope>
- </cb:scope>
<cb:scope a="a_val" b="b_val">
<test attr="$(a)" attr2="$(b)"/>
<cb:scope a="a_val_redefined">
<test attr="$(a)" attr2="$(b)"/>
</cb:scope>
</cb:scope>
其结果为:
- <test attr="a_val" att2="b_val"/>
- <test attr="a_val_redefined" att2="b_val"/>
<test attr="a_val" att2="b_val"/> <test attr="a_val_redefined" att2="b_val"/>
其中就覆盖了外层的a常量。
可以将scope应用于CCNet配置文件的Project元素,示例如下:
- <cruisecontrol xmlns:cb="urn:ccnet.config.builder">
- <cb:define WorkingMainDir="C:\Integration\"/>
- <cb:define WorkingDir="\WorkingDirectory"/>
- <cb:define ArtifactsDir="\Artifacts"/>
- <cb:scope ProjectName="Alpha">
- <project name="$(ProjectName)" queue="Q1" queuePriority="1">
- <workingDirectory>$(WorkingMainDir)$(ProjectName)$(WorkingDir)</workingDirectory>
- <artifactDirectory>$(WorkingMainDir)$(ProjectName)$(ArtifactsDir)</artifactDirectory>
- </project>
- </cb:scope>
- <cb:scope ProjectName="Beta">
- <project name="$(ProjectName)" queue="Q1" queuePriority="1">
- <workingDirectory>$(WorkingMainDir)$(ProjectName)$(WorkingDir)</workingDirectory>
- <artifactDirectory>$(WorkingMainDir)$(ProjectName)$(ArtifactsDir)</artifactDirectory>
- </project>
- </cb:scope>
- </cruisecontrol>
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define WorkingMainDir="C:\Integration\"/>
<cb:define WorkingDir="\WorkingDirectory"/>
<cb:define ArtifactsDir="\Artifacts"/>
<cb:scope ProjectName="Alpha">
<project name="$(ProjectName)" queue="Q1" queuePriority="1">
<workingDirectory>$(WorkingMainDir)$(ProjectName)$(WorkingDir)</workingDirectory>
<artifactDirectory>$(WorkingMainDir)$(ProjectName)$(ArtifactsDir)</artifactDirectory>
</project>
</cb:scope>
<cb:scope ProjectName="Beta">
<project name="$(ProjectName)" queue="Q1" queuePriority="1">
<workingDirectory>$(WorkingMainDir)$(ProjectName)$(WorkingDir)</workingDirectory>
<artifactDirectory>$(WorkingMainDir)$(ProjectName)$(ArtifactsDir)</artifactDirectory>
</project>
</cb:scope>
</cruisecontrol>
而其结果则为:
- <cruisecontrol>
- <project name="Alpha" queue="Q1" queuePriority="1">
- <workingDirectory>C:\Integration\Alpha\WorkingDirectory</workingDirectory>
- <artifactDirectory>C:\Integration\Alpha\Artifacts</artifactDirectory>
- </project>
- <project name="Beta" queue="Q1" queuePriority="1">
- <workingDirectory>C:\Integration\Beta\WorkingDirectory</workingDirectory>
- <artifactDirectory>C:\Integration\Beta\Artifacts</artifactDirectory>
- </project>
- </cruisecontrol>
<cruisecontrol>
<project name="Alpha" queue="Q1" queuePriority="1">
<workingDirectory>C:\Integration\Alpha\WorkingDirectory</workingDirectory>
<artifactDirectory>C:\Integration\Alpha\Artifacts</artifactDirectory>
</project>
<project name="Beta" queue="Q1" queuePriority="1">
<workingDirectory>C:\Integration\Beta\WorkingDirectory</workingDirectory>
<artifactDirectory>C:\Integration\Beta\Artifacts</artifactDirectory>
</project>
</cruisecontrol>
通过scope,一个变通的定义方式如下:
- <cruisecontrol xmlns:cb="urn:ccnet.config.builder">
- <cb:define WorkingMainDir="C:\Integration\"/>
- <cb:define WorkingDir="\WorkingDirectory"/>
- <cb:define ArtifactsDir="\Artifacts"/>
- <cb:define name="OurProject">
- <project name="$(ProjectName)" queue="Q1" queuePriority="1">
- <workingDirectory>$(WorkingMainDir)$(ProjectName)$(WorkingDir)</workingDirectory>
- <artifactDirectory>$(WorkingMainDir)$(ProjectName)$(ArtifactsDir)</artifactDirectory>
- </project>
- </cb:define>
- <cb:scope ProjectName="Alpha">
- <cb:OurProject/>
- </cb:scope>
- <cb:scope ProjectName="Beta">
- <cb:OurProject/>
- </cb:scope>
- </cruisecontrol>
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define WorkingMainDir="C:\Integration\"/>
<cb:define WorkingDir="\WorkingDirectory"/>
<cb:define ArtifactsDir="\Artifacts"/>
<cb:define name="OurProject">
<project name="$(ProjectName)" queue="Q1" queuePriority="1">
<workingDirectory>$(WorkingMainDir)$(ProjectName)$(WorkingDir)</workingDirectory>
<artifactDirectory>$(WorkingMainDir)$(ProjectName)$(ArtifactsDir)</artifactDirectory>
</project>
</cb:define>
<cb:scope ProjectName="Alpha">
<cb:OurProject/>
</cb:scope>
<cb:scope ProjectName="Beta">
<cb:OurProject/>
</cb:scope>
</cruisecontrol>
这样则较大的提高了配置的可维护性。
3、include元素
include元素用来包含其他的文件内容,include中根据ccnet.config文件为基准路径进行相对定位,这样就可以在ccnet.config文件里面调用所有其他文件定义的部分,以提高可维护性。如下所示:
- <cruisecontrol xmlns:cb="urn:ccnet.config.builder">
- <cb:include href="Definitions.xml" xmlns:cb="urn:ccnet.config.builder"/>
- <cb:include href="CI_Projects.xml" xmlns:cb="urn:ccnet.config.builder"/>
- <cb:include href="QA_Projects.xml" xmlns:cb="urn:ccnet.config.builder"/>
- </cruisecontrol>
<cruisecontrol xmlns:cb="urn:ccnet.config.builder"> <cb:include href="Definitions.xml" xmlns:cb="urn:ccnet.config.builder"/> <cb:include href="CI_Projects.xml" xmlns:cb="urn:ccnet.config.builder"/> <cb:include href="QA_Projects.xml" xmlns:cb="urn:ccnet.config.builder"/> </cruisecontrol>
其中Definitions.xml文件定义如下:
- <cb:config-template xmlns:cb="urn:ccnet.config.builder">
- <queue name="Q1" duplicates="UseFirst" lockqueues="Q2, Q4" />
- <cb:define name="EmailPublisher">
- <email from="buildmaster@mycompany.com"
- mailhost="localhost"
- mailhostUsername="TheMailer"
- mailhostPassword="JohnWayne"
- includeDetails="TRUE">
- <users />
- <groups />
- <modifierNotificationTypes>
- <NotificationType>Failed</NotificationType>
- <NotificationType>Fixed</NotificationType>
- </modifierNotificationTypes>
- </email>
- </cb:define>
- <cb:define name="common_publishers">
- <artifactcleanup cleanUpMethod="KeepMaximumXHistoryDataEntries" cleanUpValue="500" />
- <xmllogger />
- <statistics />
- <modificationHistory onlyLogWhenChangesFound="true" />
- <rss/>
- </cb:define>
- <cb:define name="common_nant">
- <executable>c:\nant\nant.exe</executable>
- <nologo>true</nologo>
- <buildTimeoutSeconds>240</buildTimeoutSeconds>
- </cb:define>
- <cb:define name="nant_args_CI">
- <buildArgs>clean compile</buildArgs>
- </cb:define>
- </cb:config-template>
<cb:config-template xmlns:cb="urn:ccnet.config.builder">
<queue name="Q1" duplicates="UseFirst" lockqueues="Q2, Q4" />
<cb:define name="EmailPublisher">
<email from="buildmaster@mycompany.com"
mailhost="localhost"
mailhostUsername="TheMailer"
mailhostPassword="JohnWayne"
includeDetails="TRUE">
<users />
<groups />
<modifierNotificationTypes>
<NotificationType>Failed</NotificationType>
<NotificationType>Fixed</NotificationType>
</modifierNotificationTypes>
</email>
</cb:define>
<cb:define name="common_publishers">
<artifactcleanup cleanUpMethod="KeepMaximumXHistoryDataEntries" cleanUpValue="500" />
<xmllogger />
<statistics />
<modificationHistory onlyLogWhenChangesFound="true" />
<rss/>
</cb:define>
<cb:define name="common_nant">
<executable>c:\nant\nant.exe</executable>
<nologo>true</nologo>
<buildTimeoutSeconds>240</buildTimeoutSeconds>
</cb:define>
<cb:define name="nant_args_CI">
<buildArgs>clean compile</buildArgs>
</cb:define>
</cb:config-template>
在Definitions.xml文件里面,需要使用db:config-template作为根元素使用。
本文转载自:http://blog.csdn.net/yant255/article/details/43306227
CI学习 CCNET Config 第一天的更多相关文章
- Beego学习笔记——Config
配置文件解析 这是一个用来解析文件的库,它的设计思路来自于database/sql,目前支持解析的文件格式有ini.json.xml.yaml,可以通过如下方式进行安装: go get github. ...
- Stealth视频教程学习笔记(第一章)
Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...
- 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试
20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ...
- (转)神经网络和深度学习简史(第一部分):从感知机到BP算法
深度|神经网络和深度学习简史(第一部分):从感知机到BP算法 2016-01-23 机器之心 来自Andrey Kurenkov 作者:Andrey Kurenkov 机器之心编译出品 参与:chen ...
- web前端学习python之第一章_基础语法(二)
web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...
- web前端学习python之第一章_基础语法(一)
web前端学习python之第一章_基础语法(一) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...
- 学习Nodejs的第一步
最近看了几本关于Node.js的书,本来个人技术分享网站http://yuanbo88.com/是打算用Node.js作为服务器端语言来处理后台的,后来又改成了PHP(也是自己研究,毕竟网上DEMO多 ...
- C#开发学习人工智能的第一步
前言 作为一个软件开发者,我们除了要学会复制,黏贴,还要学会调用API和优秀的开源类库. 也许,有人说C#做不了人工智能,如果你相信了,那只能说明你的思想还是狭隘的. 做不了人工智能的不是C#这种语言 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第一章:向量代数
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第一章:向量代数 学习目标: 学习如何使用几何学和数字描述 Vecto ...
随机推荐
- HTML知识速递
1.html的定义 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则 浏览器按顺序渲染网页文件,然后 ...
- struts2中struts.xml配置文件详解
struts.xml的常用配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts ...
- JDBC之代码优化
上一次我们是先实现了JDBC对数据库的增删查改操作,然后在增加新信息过程中发现了新的问题,即当某一操作失败,为了维护数据库的一致性,我们需要回滚事务.在其中我们了解了事务的工作原理及相关代码的使用. ...
- <p></p>标签为什么不能包含块级标签?还有哪些特殊的HTML标签?
最近,在码代码的时候,就是下面的这段代码,我犯了一个很不起眼,但犯了就致命的BUG. <body> <p> <ol> <li>Hello</li& ...
- python基础(三)----字符编码以及文件处理
字符编码与文件处理 一.字符编码 由字符翻译成二进制数字的过程 字符--------(翻译过程)------->数字 这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之 ...
- Python之函数返回多个值
#!/usr/bin/env python26 #-*- coding:utf-8-*- def test(): a = 10 b = 20 return a,b #返回一个元组 atuple= te ...
- 从编辑距离、BK树到文本纠错
搜索引擎里有一个很重要的话题,就是文本纠错,主要有两种做法,一是从词典纠错,一是分析用户搜索日志,今天我们探讨使用基于词典的方式纠错,核心思想就是基于编辑距离,使用BK树.下面我们来逐一探讨: 编辑距 ...
- scala(一)Nothing、Null、Unit、None 、null 、Nil理解
相对于java的类型系统,scala无疑要复杂的多!也正是这复杂多变的类型系统才让OOP和FP完美的融合在了一起! Nothing: 如果直接在scala-library中搜索Nothing的话是找不 ...
- key-value数据库-Redis
1.简介 Redis是完全开源的ANSI C语言编写.遵守BSD协议,高性能的key-value数据库. 1.1特点 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载 ...
- NodeJS寻常小毛病
在写关于NodeJS项目中常遇到的小错误 此时用到的服务器是phpstudy中的MySQL 1. First argument must be a string or Buffer 解决方法: ...