- 浏览: 118419 次
- 来自: ...
文章分类
最新评论
©Copyright 2008 Julian Simpson. All rights reserved.
英文原文: Refactor your configuration file
I was an Infrastructure Specialist at ThoughtWorks. In my role I make sure that we are building our software so it can successfully be deployed to production. In this series of blog posts I hope to pass on my top ten tips for using CruiseControl Enterprise effectively. I'm writing these with the developers or systems administrators in mind: the people who most often manage CruiseControl. However, I hope that anybody who is interested in Continuous Integration will get something from these articles.
# 5: Refactor your configuration file
请告诉我在计算机系统中重复是一件好事. 我谅你也不敢. 给我你的意见, 我们可以讨论它. 我就是那个在过去十年中, 把最好的时光花费在系统管理, 运行别人代码上的人. 这样一来你可能会猜出我是"重复是魔鬼"俱乐部的持卡会员. 如果你不是会员的话, 这可能不是给你看的文章.
重复不只是蔓延到你的业务代码中. 当你不注意的时候它同样会渗透到构建和持续集成系统中. 很可能你的团队中有个家伙就正在拷贝粘贴点什么东西到构建中. 没必要着急去阻止他们. 继续往下读你就会发现如何把CruiseControl的配置拉回正确的轨道.
这里有个关于重复的例子. 你可以看到文件中有大量的重复. 我并不是一字不差的把它从某个项目中拿出来讲(我愿意在一个叫做 Groucho 的项目中工作), 不过它离真实生活中的情景也差不多.
<cruisecontrol>
<projectname="chico"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="/var/tmp/cruise/logs/chico/status.txt"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="/var/tmp/cruise/projects/chico/"/>
</bootstrappers>
<logdir="/var/tmp/cruise/logs">
<mergedir="/var/tmp/cruise/projects/chico/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="/var/tmp/cruise/projects/chico"antscript="/var/tmp/cruise/ant/bin/ant"uselogger="true"/>
</schedule>
</project>
<projectname="groucho"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="/var/tmp/cruise/logs/groucho/status.txt"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="/var/tmp/cruise/projects/groucho/"/>
</bootstrappers>
<logdir="/var/tmp/cruise/logs">
<mergedir="/var/tmp/cruise/projects/groucho/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="/var/tmp/cruise/projects/groucho"antscript="/var/tmp/cruise/ant/bin/ant"uselogger="true"/>
</schedule>
</project>
</cruisecontrol>
幸运的是, CruiseControl中有办法来消除这种重复
CruiseControl从2005年开始就支持在config.xml中使用属性. 他们被设计成Apache Ant风格的属性, 使用美元符号和花括号: ${cruise.home}. 这个特性立马就可以用来替换你的config.xml中常数类的值, 比如你Ant脚本的位置和日志文件的目录
这是一个巨大的进步, 但还不够. 那些在配置文件本身里面定义的东西怎么办? 比如项目的名字? 作者已经提前考虑到这一点了: 有个魔法属性叫做"${project.name}"可以供你使用. 它的解释被限制在包含它的项目内, 这样你就不会在 chico 项目中引用到 harpo, 反之亦然.
来看一下引入这些属性后配置文件的样子:
<cruisecontrol>
<propertyname="cruise.dir"value="/var/tmp/cruise"/>
<propertyname="log.dir"value="${cruise.dir}/logs/"/>
<propertyname="projects.dir"value="${cruise.dir}/projects"/>
<propertyname="ant.script"value="${cruise.dir}/ant/bin/ant"/>
<projectname="chico"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="${log.dir}/${project.name}/status.txt"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="${projects.dir}/${project.name}/"/>
</bootstrappers>
<logdir="${log.dir}">
<mergedir="${projects.dir}/${project.name}/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="${projects.dir}/${project.name}"antscript="${ant.script}"uselogger="true"/>
</schedule>
</project>
<projectname="groucho"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="${log.dir}/${project.name}/status.txt"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="${projects.dir}/${project.name}/"/>
</bootstrappers>
<logdir="${log.dir}">
<mergedir="${projects.dir}/${project.name}/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="${projects.dir}/${project.name}"antscript="${ant.script}"uselogger="true"/>
</schedule>
</project>
</cruisecontrol>
看起来好多了. 如果你想改变项目的名称, 或者它引用的某个路径, 你只需要修改一个地方. 但是依然有某些样板一遍又一遍的重复着. - 也许我们可以做的更好.
属性其实有更多魔术. ${project.name}动态的随着包围着它的项目的改变而改变. 你不仅能够把它用在配置值中, 你还可以把它定义为另外某个属性值的一部分. 这对你长期忍受的配置文件来说意味着你可以为所有的项目路径声明 一个 属性, 让它惰性求值来适应每个项目. 这可能引起你的同事的困惑, 当他们第一次看到这个配置文件的时候 - "同一个属性怎么能够在这么多不同的情况下都工作呢?"
<cruisecontrol>
<propertyname="cruise.dir"value="/var/tmp/cruise"/>
<propertyname="log.dir"value="${cruise.dir}/logs/"/>
<propertyname="project.dir"value="${cruise.dir}/projects/${project.name}"/>
<propertyname="ant.script"value="${cruise.dir}/ant/bin/ant"/>
<propertyname="status.file"value="${log.dir}/${project.name}/status.txt"/>
<projectname="chico"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="${status.file}"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="${project.dir}"/>
</bootstrappers>
<logdir="${log.dir}">
<mergedir="${project.dir}/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="${project.dir}"antscript="${ant.script}"uselogger="true"/>
</schedule>
</project>
<projectname="groucho"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="${status.file}"/>
</listeners>
<bootstrappers>
</bootstrappers>
<logdir="${log.dir}">
<mergedir="${project.dir}/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="${project.dir}"antscript="${ant.script}"uselogger="true"/>
</schedule>
</project><svnbootstrapperlocalWorkingCopy="${project.dir}"/>
</cruisecontrol>
大点儿的项目中经常发生的一件事是配置文件变得很庞大. 虽然你可以做些用 XSLT 来生成配置文件之类的事(这种方法曾经弄得我很头疼), 但实际上你能够把配置文件分散到小文件中. 在CruiseControl的配置文件中这个强大的特性叫做 <include.projects> - 它允许你引用另外一个配置文件. 它和Ant中的<import>功能很像. 最终你维护着一个 config.xml 文件, 里面包含了变量定义(它们对于include进来的文件也生效), 和一堆小配置文件, 里面包含单个项目的定义. 在我现在的项目中这个特性让添加和移除项目变得非常容易. 甚至当有人删除了一个小配置文件却忘了移除对应的 <include.projects> 的时候也没问题 - 文件不存在的时候它就不会被导入进来. 跟踪 CruiseControl 配置文件的改变也变得容易很多.
下面是现在的配置文件:
<cruisecontrol>
<propertyname="cruise.dir"value="/var/tmp/cruise"/>
<propertyname="log.dir"value="${cruise.dir}/logs/"/>
<propertyname="project.dir"value="${cruise.dir}/projects/${project.name}"/>
<propertyname="ant.script"value="${cruise.dir}/ant/bin/ant"/>
<propertyname="status.file"value="${log.dir}/${project.name}/status.txt"/>
<include.projectsfile="projects/chico.xml"/>
<include.projectsfile="projects/groucho.xml"/>
</cruisecontrol>
这里是其中一个项目:
<cruisecontrol>
<projectname="chico"buildafterfailed="false"></cruisecontrol><listeners></project><currentbuildstatuslistenerfile="${status.file}"/></listeners>
<bootstrappers><svnbootstrapperlocalWorkingCopy="${project.dir}"/></bootstrappers>
<logdir="${log.dir}"><mergedir="${project.dir}/build/test/log"/></log>
<scheduleinterval="60"><antantWorkingDir="${project.dir}"antscript="${ant.script}"uselogger="true"/></schedule>
希望这能帮助让你的CruiseControl的配置文件更容易维护. 我相信持续集成应该很简单, 即使这会让我失业.
©Julian Simpson 2008. All rights reserved.
------流行的分割线------
其实 Julian 忘了说 CruiseControl 的另外一种机制: 用<plugin>来定义项目模板:
<cruisecontrol>
<propertyname="cruise.dir"value="/var/tmp/cruise"/></cruisecontrol>
<propertyname="log.dir"value="${cruise.dir}/logs/"/>
<propertyname="project.dir"value="${cruise.dir}/projects/${project.name}"/>
<propertyname="ant.script"value="${cruise.dir}/ant/bin/ant"/>
<propertyname="status.file"value="${log.dir}/${project.name}/status.txt"/>
<pluginname="project"buildafterfailed="false">
<listeners>
<currentbuildstatuslistenerfile="${status.file}"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="${project.dir}"/>
</bootstrappers>
<logdir="${log.dir}">
<mergedir="${project.dir}/build/test/log"/>
</log>
<scheduleinterval="60">
<antantWorkingDir="${project.dir}"antscript="${ant.script}"uselogger="true"/>
</schedule>
</plugin>
<projectname="chico">
<projectname="groucho"/>
如果结合模版和include.projects, 最终的配置文件可能会非常简单; 只不过CruiseControl有一种限制, 模版必须在主配置文件中定义才有效.
发表评论
-
The Object Primer
2004-12-11 11:21 5911,书名 被翻译成“ ... -
错误处理规范
2004-12-11 16:47 758错误处理规范 〇、概念澄清 概念 解释 错误 ... -
Java,误解为何如此之深
2005-08-24 13:50 593前几天被电话面试,问J ... -
Java:画蛇添足的编码规范
2005-09-02 13:13 613前几天公司培训编码规范: 第n条: ... -
synchronized : 规则, 推论与实践
2007-07-23 22:32 46714.3.Synchronization. Rule ... -
交互设计: 股市帮凶
2008-05-04 21:30 642同事 Y 在线操作股票时, 把"买入"点成 ... -
交互设计: 火车上的厕所
2008-05-26 17:17 609有人在动车组的厕所前等了很久, 直到乘务员路过说厕所是被锁住了 ... -
设计原则与模式: 案例介绍--CppUnit
2008-06-01 20:15 621设计原则与模式: 案例介绍--CppUnit CppUnit ... -
工作流:形参,实参,相关数据
2004-12-11 11:40 676关于形参,实参,相关数据 一、形参(FormalParame ... -
工作流:第一次发版,过程总结
2004-12-11 11:42 712交流 即时讨论:小组成员咫尺之遥,有问题立即提出并解决 ... -
工作流:第一次发版,设计总结
2004-12-11 11:43 613整体 面向接口:消息系统,持久系统等,其实现都是可替换 ... -
Beyond Workflow : An Introduction to Vitria BusinessWare
2005-09-26 10:13 804一、简介 Busines ... -
Vitria BusinessWare: 存储与访问安全
2006-03-26 15:45 746事实上,BusinessWare使用LDAP做为存储机制和 ... -
Vitria BusinessWare: 平台与软件总线
2006-04-01 12:59 842经过一段时间的使用 ... -
Vitria BusinessWare: Web Services
2006-04-01 14:30 740BusinessWare的Web Services ... -
Web Services:自洽,编码,交换模型
2006-04-01 16:02 6791, 自洽 以前曾经写过: 目前WebServi ... -
Web Services:WSDL 1.1 规范中的几个错误
2006-04-01 16:40 721读完了WSDL 1.1的规范,令人惊讶的是发现似乎例子中有几个 ... -
C++/CLI:被忽视的集成技术
2006-05-17 20:02 755十几行代码,就使一个重要的旧系统组件,完全融入了基于.Ne ... -
AJP/JK:异构Web平台的集成技术
2006-05-25 21:44 710Tomcat Connector 可以将Tomcat ... -
Vitria BusinessWare: 事件与端口
2006-05-27 17:24 660Event BusinessWare是一个事件驱动的系统 ...
相关推荐
- **CruiseControl.doc**:可能是一份CruiseControl的入门教程或者详细使用指南,涵盖安装配置、基本概念、常用命令和最佳实践等内容。 - **CruiseControl2.doc**:可能是关于CruiseControl的进阶使用,可能涉及...
CruiseControl是一款持续集成工具,它能够自动化地构建、测试和部署软件项目,极大地提高了开发效率和产品质量。在本文中,我们将深入探讨如何配置CruiseControl以实现定时运行,确保项目始终保持最新状态。 首先,...
5. **CruiseControl简介及使用举例**:风之影在JavaEye上的文章可能对CruiseControl进行了简要介绍,并通过实例展示了CruiseControl的关键功能,如版本控制集成、构建触发器和构建报告。 6. **向CruiseControl中...
### [CruiseControl] Binary安装与启动指南 #### 一、CruiseControl简介 CruiseControl 是一个持续集成工具,用于自动化构建过程并提供实时反馈,帮助开发团队尽早发现问题。它支持多种构建工具如 Ant 和 Maven,...
**持续集成实践之CruiseControl** 在软件开发领域,持续集成(Continuous Integration,简称CI)是一种重要的实践,它强调开发者频繁地将代码更改合并到主分支,以尽早发现并解决问题。CruiseControl是一款开源的...
**持续集成之CruiseControl.rb** CruiseControl.rb是一款开源的持续集成工具,主要用于自动化构建、测试和部署软件项目。它是由ThoughtWorks公司开发的,是CruiseControl.NET的Ruby版本,因此在Ruby社区中被广泛...
CruiseControl是一款持续集成工具,它能够自动化地执行软件项目的构建、测试和部署流程,以确保代码的质量和项目的稳定性。本篇文章将详细介绍CruiseControl的基本概念、安装过程、配置方法以及一个简单的使用示例。...
CruiseControl是一款持续集成工具,它能够自动化地构建、测试和部署软件项目,极大地提高了开发效率和产品质量。本文将深入探讨CruiseControl的核心概念、配置方法以及如何在实际项目中运用。 CruiseControl的主要...
CruiseControl 是一个开源的持续集成工具,用于自动化软件构建、测试和部署的过程。它通过监控版本控制系统中的变更,自动触发构建任务,及时发现并解决代码集成中的问题,从而提高开发团队的效率和软件质量。本...
标题与描述概述的知识点主要涉及了使用CruiseControl与Maven2进行持续集成的配置流程。这是一项在软件开发过程中非常关键的技术实践,它能够自动检测代码库中的更新,并自动执行构建、测试以及部署等任务,从而确保...
主题:持续集成及CruiseControl技术交流 在提升软件质量、降低研发风险、拒绝浪费方面,处于敏捷实践领域的持续集成(Continuous Integration,CI)起到重要作用。持续集成能够解决研发工作中的80%任务(日常),...
本教程将详细讲解CruiseControl的学习与实践。 **第一章 CruiseControl实践** 1.1 CruiseControl架构 CruiseControl的核心是一个服务器,它负责监听源代码仓库的变更,并在检测到变更时触发构建过程。这个过程包括...
CruiseControl是CI服务器的老者,诞生已是多年,在许多方面,CruiseControl服务器已经成为持续集成实践的同义词。而现在,CruiseControl已发展成为一个家族式系统,包括CruiseControl.java、CruiseControl.net、...
"利用CruiseControl软件进行持续集成" 在软件开发过程中,持续集成是一个非常重要的步骤,它可以帮助开发团队更好地合作和跟踪项目的进度。CruiseControl是一种流行的持续集成工具,能够自动化地构建、测试和部署...
cruisecontrol.war 文件,你可以直接将这个文件 COPY 到你的%TOMCAT_HOME%\webapps 目录下,不 过这种方式通常都会出错,前 面我们讲过CC的WEB组件要访问我们的项目build 的状态文件,而下载的 CC2.2 里面自带的 ...
【CruiseControl 持续集成环境搭建】 CruiseControl 是一款开源的持续集成工具,它的主要任务是在软件开发过程中,通过监控版本控制系统(如 SVN)的变化或者按照预设时间进行定期构建,以确保项目的持续集成。...
CruiseControl.NET 是 .NET 平台下的持续集成工具,CruiseControl (Java) 的 .NET 移植版本。CruiseControl是一个针对持续构建程序(项目持续集成)的框架,它包括一个email通知的插件,Ant和各种各样的CVS工具。Cruise...