[转]Ivy入门学习

[原文] http://www.blogjava.net/aoxj/archive/2009/03/31/263012.html

    欢迎使用ivy参考文档,如果你完全不了解ivy,请在深入阅读这份参考文档之前,简单了解一下它的特性,FAQ和教程。


    参考概要:

    这份文档被分解为以下几个部分

    一. 介绍
          1. 术语 (English / 中文)
        这个部分介绍一些在ivy文档中到处使用的词语,例如组织,模块,配置,设置

          2. 主要概念 (English / 中文 上/下)
        这个部分介绍ivy中使用的主要概念:依赖解析器,变量,表达式,另外还有还对ivy的主要概念---模块配置做了良好介绍。

          3. ivy如何工作
        正如标题显示的,在这里你将得到一些ivy内部是如何工作的说明,这可以帮助你更好的理解和定制使用。   
          4 安装
        这个部分讲述如何安装ivy

    二. Ivy Settings Files
        This part is dedicated to the specification of the settings file of Ivy (usually called ivysettings.xml). It also gives

the list of built-in dependency resolvers available in ivy.

    三. Ivy Files
        This part is the reference of the specification of the module descriptors, the ivy files in which you describe your dependencies. If you have any question of what can be done or not in an ivy file, you will have the answer here.

    四. Ant Tasks
        This part describes how to use ivy from ant. It's in this section that all ant tasks brought by ivy are specified.

    五. Using standalone
      Even though Ivy is most often used from ant, it can also be used from the command line. This page describes how you can do it.

    译者注:在学习ivy的过程中陆陆续续的翻译了一些ivy的参考文档,现在准备将这个工作进行到底,将官方网站上完整的ivy参考文档翻译成中文。上面内容是参考文档的目录,翻译完成的部分我会陆续更新为中文并加入链接。

    英文文档地址请见:http://ant.apache.org/ivy/history/2.1.0-rc1/reference.html

    水平有限,出现错误的地址请多多指正
--------------------------------------------------------
Ivy<1>   
 maven很强大,但是远不完美,令人烦恼的地方也不少。看到Ivy似乎日渐成熟,试试看这个小东西表现如何,毕竟后面有那个强大的我喜欢的ant。

    折腾了一番,整理出来点东西,分享给对ivy同样感兴趣的朋友。依然是"初学"系列,提供给新手入门使用。

一. 下载安装

    从官网http://ant.apache.org/ivy/下载到最新的ivy2.0.0正式版,选择的是with dependencies的包。

    在安装ivy之前,请先安装好ant1.6以上版本,因为Ivy是基于ant的。

    参照官网的安装,将下载下来的ivy安装包解压,然后复制ivy的jar文件到ant的lib目录下(ANT_HOME/lib)。设置系统属性IVY_HOME到ivy的安装目录,比如G:\soft\ivy\ivy200。

    另外一个简单的安装方法,就是直接到ivy的src/example/hello-ivy 目录下执行ant,会从网上下载ivy并安装的。

二. 设置工作目录

    Ivy 使用"ivy.default.ivy.user.dir"作为工作目录,ivy通过以下方式确认该目录的具体路径:

    1. 查找变量ivy.default.ivy.user.dir
    2. 如果没有找到,查找变量ivy.home
    3. 如果还没有找到,查找变量user.home,然后使用user.home/.ivy目录

    默认安装而没有专门设置前,前两个变量不存在,因此ivy就会使用user.home作为默认工作目录.

    Ivy 使用cache目录来存放缓存文件,ivy通过以下方式确认该目录的具体路径:
    1. 查找变量ivy.cache.dir
    2. 如果没有找到,使用ivy.default.ivy.user.dir/cache

    默认安装而没有专门设置前,前ivy.cache.dir变量不存在,因此ivy就会使用 ivy.default.ivy.user.dir/cache,由于ivy.default.ivy.user.dir在该情况下默认使用 user.home,因此最后的结果就是使用user.home/cache目录.

    修改默认工作路径的方法,很明显,设置上述的几个变量值即可。比如需要将ivy.default.ivy.user.dir设置到一个特定的目录而不是使用当前操作系统的user.home路径,对于ivy,可以通过设置ant属性的方式。比如修改build.xml文件,增加以下内容
    <property name="ivy.default.ivy.user.dir" value="G:\soft\ivy\userdir" />
    这样就将工作路径修改过去,cache目录也随之改变,避免重新安装操作系统/安装多操作系统等情况下对当前操作系统和用户的依赖。

    由于build.xml文件通常都是项目文件,需要提交到cvs、subversion等版本控制系统中,因此直接在里面写路径不大适合,一旦修改需要改动所有项目的build.xml,而且不同开发人员要求路径相同,不大合理。考虑到ant是可以方便读取系统环境变量的,因此可以用环境变量来定义具体的路径,ant简单使用该环境变量:
    设置环境变量env.ivy.default.ivy.user.dir=G:\soft\ivy\userdir
    build.xml中这样引用:
    <property environment="env"/>
    <property name="ivy.default.ivy.user.dir" value="${env.ivy.default.ivy.user.dir}" />

    以上目录使用规则可以直接看ivy的源代码,很清晰,类org.apache.ivy.core.settings.IvySettings中 IvySettings()的构造函数很容易看出上面的规则。(惭愧,刚学ivy,对配置不熟悉,又找不到相关的配置说明文档,只好蛮干了)


三. 配置文件路径
    ivy使用变量名ivy.settings.file来设置配置文件路径,由于没有找到相关的设置文档,因此干脆打开源文件看代码。
    在类org.apache.ivy.ant.IvyAntSettings中,函数defineDefaultSettingFile()中有相关的代码:

    1. 查找变量名ivy.settings.file
    settingsFileName = variableContainer.getVariable("ivy.settings.file");

    2. 可能的路径,依次是项目BaseDir(应该是ant的build.xml文件中定义的BaseDir,通常是项目根路径),当前路径,很奇怪居然不查找诸如ivy.default.ivy.user.dir的路径,甚至连ivy.settings.dir都不去查找,莫名其妙
    File[] settingsLocations = new File[] {
                new File(getProject().getBaseDir(), settingsFileName),
                new File(getProject().getBaseDir(), "ivyconf.xml"),
                new File(settingsFileName),
                new File("ivyconf.xml")
        };

    3. 上面四个路径依次查找
        for (int i = 0; i < settingsLocations.length; i++) {
            file = settingsLocations[i];
            verbose("searching settings file: trying " + file);
            if (file.exists()) {
                break;
            }
        }

    4. 如果没有找到,则取默认设置
    if (!file.exists()) {
                info("no settings file found, using default...");
                file = null;
                url = IvySettings.getDefaultSettingsURL();
        }
    默认配置文件是ivy.jar包中的org.apache.ivy.core.settings.ivysettings.xml,如果不做任何相关配置,一般都使用这个默认配置。

    了解ivy是怎么工作了,想配置就方便了。比如如果希望为当前项目单独设置,则可以:
    1. 在当前项目BaseDir目录下放置ivyconf.xml文件
        new File(getProject().getBaseDir(), "ivyconf.xml")
        这个是最简单的方案了,奇怪的是这里的文件名是ivyconf.xml,很郁闷,我用ivysettings.xml测试了好久都不生效,原来根结在这个地方。风格不统一,估计是新老版本兼容问题,幸亏可以看到源代码。

    2. 或者同时设置ivy.settings.file为要求的文件名,将该文件放置在项目BaseDir目录下
        new File(getProject().getBaseDir(), settingsFileName)
        比如设置ivy.settings.file=ivysettings.xml,这样可以和jar包中的文件名保持一致。似乎用处不大?

    3. 为了让所有项目统一使用相同配置,可以考虑直接将ivy.settings.file指向一个公共的配置文件
        比如设置ivy.settings.file为${env.ivy.default.ivy.user.dir}/ivysettings.xml
        这样就不必每次都重复设置相同的内容,比如ivy的public repository,默认是使用maven2的官网仓库,我们可以修改为使用maven的本地私库,如nexus之类。

    build.xml中的设置:
    <property environment="env"/>
    <property name="ivy.default.ivy.user.dir" value="${env.ivy.default.ivy.user.dir}" />
    <property name="ivy.settings.file" value="${ivy.default.ivy.user.dir}/ivysettings.xml" />


四. 和nexus集成

    我喜欢使用nexus来搭建maven2的私服,即使家里机器上的私服只有我一个人用......
    因此想让ivy能连到我现有nexus私服,google了一下找到解决的方法,实验成功,只需要修改两个地方:

    1. ivysettings.xml
        将原有的
    <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
        修改为
    <include url="./ivysettings-public.xml"/>

    2. 在ivysettings.xml相同目录下放置ivysettings-public.xml文件
        实际从ivy.jar包中copy出对应文件,然后修改
        <ibiblio name="public" m2compatible="true" root="http://192.168.0.30:8081/nexus/content/groups/public/"/>
        注意这里的name="public"不能改,否则会报错。

        有关public, shared, private三个repository的资料,请参考官方文档,说明的很细致
        http://ant.apache.org/ivy/history/latest-release/tutorial/defaultconf.html

added in 2009-04-22:
        上面的内容有点乱,三个星期后我在另一台机器上安装ivy时,对照本文看居然都没有直接搞定,又浪费了点时间折腾......
        决定再啰嗦一点,下面是具体操作步骤,这次足够简单直接了:
1) install ant1.6+
    set env ANT_HOME=G:\soft\ant
    set Path, add ANT_HOME/bin

2) install ivy
    set env IVY_HOME=G:\soft\ivy\ivy200
    set env ivy.default.ivy.user.dir=G:\soft\ivy\userdir

3) config ivy for all projects and users
    1. copy ivysettings.xml to userdir
    2. copy ivysettings-public.xml to userdir
    3. open ivysettings-public.xml, edit m2 URL

4) add ivy setting to ant build.xml of project
    ......
    <property environment="env"/>
    <property name="ivy.default.ivy.user.dir" value="${env.ivy.default.ivy.user.dir}" />
    <property name="ivy.settings.file" value="${ivy.default.ivy.user.dir}/ivysettings.xml" />
    ......

added in 2009-05-29:
    在linux上测试的时候,才发现一个问题,ivy.default.ivy.user.dir是不能作为linux下的环境变量名的!为了保持一致,只好修改为IvyDefaultUserDir。
    即:
    set env IvyDefaultUserDir=G:\soft\ivy\userdir
    ......
    <property environment="env"/>
    <property name="ivy.default.ivy.user.dir" value="${env.IvyDefaultUserDir}" />
    <property name="ivy.settings.file" value="${ivy.default.ivy.user.dir}/ivysettings.xml" />

--------------------------------------------------------
Ivy<2>

在ivy中使用了很多术语,他们的定义如下:

    * Organisation / 组织
    * Module / 模块
    * Module Descriptor / 模块描述符
    * Artifact / 制品
    * Type of an artifact / 制品类型
    * Artifact file name extension / 制品文件扩展名
    * Module Revision / 模块修订本
    * Branch / 分支
    * Status of a revision / 修订本状态
    * Configurations of a module / 模块配置
    * Ivy Settings / ivy设置
    * Repository / 仓库

一. 概述

    下面的插图展示了所有的关键术语:

    http://ant.apache.org/ivy/history/2.1.0-rc1/images/ivy-terminology.png

二. Organisation / 组织

    组织可以是公司,个人,或者仅仅是任何开发软件的一组人。原则上,ivy仅处理单一级别的组织,这意味着他们在ivy模块描述符中拥有一个扁平的命名空间。因此,如果使用分层的命名习惯,用ivy的描述符只能描述树形组织结构。组织名用来将同一个团队生产的软件保持一致,仅仅是帮助定位他们发布的。
作品。

    在ivy中通常使用反转的域名作为组织名,因为域名是独一无二的。域名为www.example.com的公司可以使用com.example,或者如果他们有多个团队,他们的组织名可以以com.example开头(例如com.example.rd, com.example.infra, com.example.services)。组织名并不强制要求一定要是域名反转,或者全局唯一,但是唯一的名字是高度推荐的。被广泛认可的商标或者商业名的拥有者可以选择使用他们商标名。如org.apache, ibm, jayasoft

    注意ivy的“组织”非常类似maven POM 中的"groupId"。

三. Module / 模块

    模块是一个完备的可重用的软件单元,带有一个修订版控制方案。

     ivy仅关心模块的发布比如大家熟知的"artifacts",还有用于表示他们的模块描述符。这些发布,包括模块的每一个修订版本,在仓库中管理。换句话说,对于ivy,一个模块就像一个修订版本链,每个修订版本由一个描述符和一个或多个artifact构成。例如:hibernate- entitymanager, ant

模块描述符
    模块描述符是识别模块的一般方法:识别符(组织,模块名,分支和修订版本),已发布的制品,可能的配置和依赖。

    在ivy中最通用的模块描述符是Ivy Files,带有ivy特定语法的xml文件,通常被称为ivy.xml。

    但是既然ivy同样兼容maven2的原数据格式(名为pom, Project Object Model, 项目对象模型), pom文件也可以作为模块描述符使用。

    而且由于ivy支持可插入式的模块描述符解析器,因此几乎可以使用任何东西作为模块描述符。

四. Artifact / 制品

    制品是一个为模块修订版本的发布而准备的单独文件,作为开发的一个产品。

    通常推荐使用压缩包格式,因为容易管理,传送和存储。同样的理由,通常一个模块只有一个或者很少的制品。无论如何,制品可以是任意文件类型,在一个单独的模块中可以申明任意数量。

    在java的世界种,通常的制品是Java archives 或者说jar文件。在很多情况下,模块的每个修订版本只发布一个制品(例如 jakarta-log4j-1.2.6.tar.gz), 但是他们中的一些发布多个制品,取决于模块的使用。(像 apache-ant 二进制和源文件,分别打包为zip, gz 和bz2 格式).例如: ant-1.7.0-bin.zip, apache-ant-1.7.0-src.tar.gz

制品类型

    制品类型是一个特别类型的制品范例的范畴(翻译的很晕,原文:The artifact type is a category of a particular kind of artifact specimen.)。这是基于制品的已制定计划或者制品如何提供的分类法,而不是包的格式类型或者制品如何发布。

    虽然制品的类型可能暗示它的文件格式,但是他们是两个不同的概念。制品的文件扩展名和它的格式联系更紧密。例如,Java archives的情况,制品类型"jar"显示它确实是一个Java archive文件,符合JAR文件规范。它的文件扩展名只是凑巧也是"jar"。另一方面,对于源文件发布包,制品类型可能是"source",虽然文件扩展名可以是"tar.gz", "zip", "java", "c", 或 "xml"。所以,制品类型基本上是用来解释它的目的的抽象功能类别,而制品文件扩展名是更加具体的技术上的文件格式和名称的标记。

    定义模块的适当的制品类型由开发组织决定。通常的选择包括: "jar", "binary", "bin", "rc", "exe", "dll", "source", "src", "config", "conf", "cfg", "doc", "api", "spec", "manual", "man", "data", "var", "resource", "res", "sql", "schema", "deploy", "install", "setup", "distrib", "distro", "distr", "dist", "bundle", 等等.

    模块描述符不是真正的制品,但是他们可以作为一个制品类型,比如"descriptor"(ivy file 或者 Maven POM).

    电子签名或者摘要本身不是真正的制品,但是他们可以再仓库中被找到。他们也被作为一种制品类型,例如"digest" (md5 or sha1)。

五. 模块修订本和状态

模块修订本

    模块的每一个被发布的唯一状态都被分配一个唯一的修订本编号或者版本名。ivy可以帮助为模块的发布生成修订本编号,并将修订本发行到仓库中,但是修订本控制的其他方便,尤其是源文件修订,必须由单独的版本控制系统管理。

    因此,对于ivy,修订本经常对应模块的一个发布版本。它可以是public, shared 或 local delivery,一个发布,一个里程碑或者一个集成构造,一个alpha或者bata版本,一个nightly build, 或者甚至是一个持续构造。它们都被ivy视为修订本。

    在某些情况下,源文件控制系统的源文件修订本编号可以被用来作为模块的修订本编号,但是这种用法非常少见。它们是两个不同的概念,即使模块的修订本编号是完全或部分从源文件修订本编号中复制过来。

分支

    分支对应于源文件控制管理工具中的分支(有时是stream/流)的标准含义。head, 或者trunk, 或者main stream都被ivy视为分支。

修订本状态

    模块的状态显示模块的修订本的稳定程度。它被用来统一所有模块依赖的状态,防止在模块的release中使用依赖的集成修订本。

    ivy默认定义三种状态

    * integration/集成: continuous build,nightly build等产生的修订本归于此类
    * milestone/里程碑: 发布给公众但是还没有真正完成的修订本归于此类
    * release/发行: 完整测试并被打好标签的修订本归于此类

    在1.4版本之后,这个列表可以在settings file/设置文件中配置。

六. 模块配置

    模块配置是使用或者构建一个模块的方法。如果同一个模块有不同的依赖,基于如何使用,在ivy中这些不同的依赖组合被称为它的配置。

    一些模块可能以不同的方式被使用(考虑hibernate,可以在应用服务器内部或者外部使用),而这种方式可能改变你需要的制品(这种情况下的 hibernate, jta.jar仅仅当它被在应用服务器外部使用时才需要)。此外,模块可能仅仅在build时需要一些其他模块或者制品,而在运行时需要其他一些。所有这些不同的使用或者构建模块方式在ivy中被称为模块配置。


    更多配置和他们在ivy中如何被使用的细节,请参考主要概念的页面。

七. ivy设置

  ivy设置文件是xml文件,用于配置ivy来指示从哪里可以找到模块和如何找到模块。

设置的历史

    在ivy2.0之前,设置文件被称为配置文件,通常名为为ivyconf.xml。这导致了模块配置和ivy配置文件之间的混淆,因此被重命名为配置文件。如果你偶尔发现ivyconf文件,或者某些被称为配置文件的东西,大多数情况下都只是因为它是没有更新的信息(文档,指南和文章). 可以随便报告任何类似这样的问题,如果你在这封文档中发现这样的不一致。

八. 仓库

    在ivy中,被称为仓库的是ivy用来发现你要求的模块的制品和描述符的分布站点位置(也就是大多数情况下的ivy文件)。ivy可以使用非常精巧的配置的复杂仓库。你可以使用Dependency Resolvers来做这些。

--------------------------------------------------------
Ivy<3>

    英文原文:http://ant.apache.org/ivy/history/2.1.0-rc1/concept.html

    因内容太长而拆分,下面是第一部分:

一. 依赖解析器

    依赖解析器是ivy中使用的可插入是的类:
    * 发现ivy文件中的依赖
    * 下载依赖的制品

    制品下载的概念很大:制品可以在网站上,或者在你机器上的本地文件系统上。下载是从仓库取文件放到ivy缓存的行为。
    而且,解析器的职责是找到ivy文件并下载制品,这有助于实现不同的解析策略。
    如你所见,依赖解析器可以被认为是负责描述仓库的类。
    如果你想知道在ivy中有哪些解析器可用,你可以转到对应的配置章节。

二. 模块配置说明

    模块配置在术语页面已经被描述,是用来使用或者构建模块的方法。配置是ivy的重要部分,需要更多的说明。
    当你定义一种方式来使用或者构建模块时,你可以在这个配置中定义哪些制品被这个模块发布,并且你还可以在这个配置中定义哪些依赖是需要的。

    此外,因为ivy中的依赖是以模块而不是制品来表述,因此能够在你定义的模块中定义依赖的配置是必须的就显得很重要了。这就是配置映射。

    如果你仅仅使用单一的模块并且不想操心配置,你可以不理会他们。它们依然存在,导致ivy无法在没有配置的情况下工作。但是大多数时候,如果你不定义任何东西,ivy会假设你的模块的制品在所有的配置中发行,并且在所有的配置中所有的依赖配置都是必须的。并且在单一模块的情况下工作正常。但是无论何时你想在一个模块内部分隔事物,或者更多的控制发行的东西并通过依赖解析,配置会满足你的大多数要求。

    更多如何定义模块配置,定义制品用哪个配置发布和定义配置映射的细节,请参考ivy文档。配置教程是一个可以教会你学到更多关于这个概念的东西的好地方。

三. 变量

    在配置的过程中,ivy容许定义ivy变量。ivy变量可以被视为类似ant属性,而且使用方式很相似。特别是,在配置文件中使用属性标签来装载包含ivy变量和值的属性文件。
    但是,ant属性和ivy变量之间的最大差别在于ivy变量可以被覆盖,然而ant属性不可以,而且它们在不同的环境下定义。
    实际上当配置完成时,所有ant属性都被导入到ivy变量(如果是从ant中调用ivy)。这意味着如果你在调用配置之后定义一个ant属性,它讲无法作为一个ivy变量来访问。另一方面,ivy变量不能导出到ant,所有如果你在ivy中定义ivy变量,不要试图作为ant属性来使用它们。

    为了使用ivy变量,你必须遵循和ant属性相同的语法:
    ${variablename}
    这个的variablename是变量名

    最后,同样重要的是知道变量代入的时间点。带入是尽可能快的。这意味着当ivy遇到一个变量引用,如果这个变量被定义了,它会试图代入。结果是,这个变量在之后的任何改动都不会影响这个已经代入的值。
    此外,在ant环境中,一串变量将通过ant属性文件装载机制被默认设值(实际上他们被作为ant属性第一次装载,然后被导入为ivy变量,见ant任务),甚至在ant属性自身也将在装载时立即代入,有效地使得仅仅通过ivysettings.properties文件来覆盖某些变量变得没有可能。某些变量因此只能通过ant属性来重载。
    此外,同样非常重要的是理解ivy变量和ivy模式标记(pattern tokens)之间的不同。请翻阅模式的章节来理解什么是模式标记。

四. 模式

    ivy模式在很多依赖解析器和ivy任务中被使用,是构成ivy工作方式的简单方法。
    首先我们给出一个例子。距离说你可以通过提供一个查找制品的模式来配置一个文件系统依赖解析器。这个模式类似这样:
    myrepository/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]

    这个模式表明我们使用的仓库是在被称为myrepository的目录中。
    在这个目录中有我们要查找的名为组织和模块的目录。那么每个模块一个目录,名字就是模块名。然后在每个模块目录中我们发现每个制品类型(jars, wars, ivys, ...)有一个目录,在这些目录中我们发现制品被命名为制品id,加一个连字符(横杠),然后是修订本,逗号,制品的扩展名。
    不是很难理解吧?就是这样,现在你能理解模式的概念了!
    多解释一点,模式是由标记组成的,当赋值给特定的制品或模块时标记被替换为实际的值。这些标记和变量不同,因为它们为每个制品做不同的替换,然而变量通常是相同的值。

    你可以在模式中混合使用变量和标记:
    ${repository.dir}/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]

    标记是否有用取决于模式在哪里被使用(例如赋值给制品或者模块),但是这里是所有目前可用的标记:

    * [organisation] 组织名
    * [module] 模块名
    * [branch] 分支名
    * [revision] 修订本
    * [artifact] 制品名(或者id)
    * [type] 制品类型
    * [ext] 制品文件扩展名
    * [conf] 配置名
    * [originalname] (since 1.4) 原始的制品名(包括扩展名)

    类型和扩展名的不同在ivy文件文档中已经解释过了。

    从1.2开始, [organization] 可以被 [organisation] 替代使用.
    从1.3开始, 在模式中可以使用可选部分。

    这使得当标志没有定义时可是避免某些输入,而不是仅仅得到一个空的标记。括号被用于界定可选部分,并且在括号中只能有一个标记。因此如果在你在用'(' 和 ')'包围一个标记,如果标记没有值则在括号之间的任何其他文本都将被忽略。

    例如, 假设有这样一个模式: "abc(def[type]ghi)"
    type = "jar" -> 模式展开为: abcdefjarghi
    type = null 或者 "" -> 模式展开为: abc

    更实际的例子:模式[artifact](-[revision]).[ext]
    让你同时接受在修订本被设置时的myartifact-1.0.jar和没有设置修订本时的myartifact.jar(而不是myartifact-.jar)。在你需要保持对制品名的控制时非常有用。

    从1.4开始,附加属性可以在模式中被当成任意其他标记被使用。

五. 最新策略

    ivy经常需要知道两个修订本之间哪个是最新。为了知道这个,ivy使用"最新策略"的概念。当然,有多个方法可以考虑一个修订本是否是最新。你可以选择一个已经存在的或者插入你自己的。
    但是在知道那个修订本是最新的之前,ivy需要有能力去考虑一个模块的多个修订本。因此ivy不得不从目录下得到一个文件列表,为此需要使用依赖解析器。因此在奇怪为什么ivy没有得到你最新的修订本前,请检查你使用的依赖解析器是否和最新的修订本兼容。
    最后,为了得到模块的不同修订本,大多数时候你需要在你的模式中使用[revision]标记,这样无论revision是什么ivy都能得到匹配这个模式所有的文件。只有这样来时使用最新策略来检测那个修订本是最新的。

    ivy有三个内建的最新策略:

    * latest-time
    比较修订本时间来知道哪个是最新的。虽然相对来说这通常是一个好的策略,但是它有一个缺点,和远程仓库进行推断是有代价的。例如如果你使用ivyrep,ivy不得不在知道哪个是最新的之前询问http服务器每个ivy文件的日期。

    * latest-revision
    把修订本进行字符串比较,使用接近于php version_compare 函数的算法。这个算法被用于评估某些文本的特殊含义。例如,这这个策略中,1.0-dev1 被认为在1.0-alpha1之前, 1.0-alpha1在1.0-rc1之前, 1.0-rc1在1.0之前, 1.0在1.0.1之前.

    * latest-lexico
    把修订本进行字符串比较,使用辞典顺序(这个方法被java strong 比较使用)

六. 冲突管理器

    冲突管理器可以在冲突的模块修订本列表中选择需要保留的修订本。
    如果修订本对应相同的模块,举例说相同的组织/模块名对,那么称为冲突的修订本列表。
    可用的冲突管理器列表在可以冲突管理器页面可以得到。
    想得到更多如果配置冲突管理器的细节,请看ivy文件参考的冲突章节。

--------------------------------------------------------
Ivy<4>

 ivy中文参考文档(4)-主要概念(下)
    ivy中引入了一些自己的概念,了解并理会这些概念对ivy的学习使用是有帮助的。这里翻译一下官网的介绍ivy主要概念的文章,原文在此:http://ant.apache.org/ivy/history/2.1.0-rc1/concept.html

    因内容太长而拆分,下面是第二部分:


六. 冲突管理器

    冲突管理器可以在冲突的模块修订本列表中选择需要保留的修订本。

    如果修订本对应相同的模块,举例说相同的组织/模块名对,那么称为冲突的修订本列表。

    可用的冲突管理器列表在可以冲突管理器页面可以得到。

    想得到更多如果配置冲突管理器的细节,请看ivy文件参考的冲突章节。

七. Pattern matcher 模式匹配

    从1.3之后在很多地方ivy使用模式来匹配一系列对象。例如,当通过使用匹配所有想排除的模块的模式来声明一个依赖时,你可以立即排除这多个模块。

    ivy使用可插入式的模式匹配器来匹配哪些对象名。默认定义好的有3个:

    * exact
        This matcher matches only string when they are equal to the pattern one
        这个匹配器仅匹配字符串,要求和模式相同。

    * regexp
    这个匹配器容许你使用java1.4或者更高版本的Pattern类支持的正则表达式

    * glob
    这个匹配器容许你使用unix风格的glob匹配器,仅有的能使用的字符是匹配任何字符串的*和精确匹配单个字符的?。注意仅仅当jakarta oro2.0.8在classpath中时这个匹配器才可以使用。

    同样请注意,在任何匹配器中,字符'*'有匹配任意东西的特殊含义。对于不依赖匹配器的默认值尤其有用。


八. 附加属性

    从1.4版本之后在ivy的xml文件中有几个标签是可以通过被称为附加属性的东西来进行扩展。想法很简单:如果你需要更多信息来定义你的模块,你可以添加你需要的属性,然后能够像访问其他属性一样访问它,比如在你的模式中。
    从2.0版本之后,可以并且推荐为你的附加属性使用xml命名空间。使用ivy附加命名空间是最简单的添加你自己的附件属性的方法。

    例如:
    这里是一个ivy文件,属性'color'设置为blue:
    <ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation="apache"
           module="foo"
           e:color="blue"
           status="integration"
           revision="1.59"
    />
    </ivy-module>

    这样当你定义一个基于foo的依赖时你就必须使用附加属性。那些附加属性 被作为标识符实际使用,类似org,name和revision。
    <dependency org="apache" name="foo" e:color="blue" rev="1.5+" />
    你还可以这样定义你的仓库模式:
    ${repository.dir}/[organisation]/[module]/[color]/[revision]/[artifact].[ext]
    注意在模式中科你必须使用非限定属性名(不带命名空间前缀)

    如果你不想使用xml命名空间,这是可以做到的,但是你需要使ivy文件验证失效,因为你的文件不再符合任何正式的ivy xsd。查看设置文档来得知如何使验证失效。


九. 校验和
    从1.4版本后,ivy容许使用校验和,被称为digester,来验证下载文件的正确性。
    目前ivy支持MD5和sha1算法。

    使用MD5还是sha1的配置可以是全局的,或者是由依赖解析器设置。全局是使用变量ivy.checksums来列举要进行的检测(仅支持md5和sha1),在每个解析器上你可以使用属性

checksums来覆盖全局设置。

    设置是逗号分隔的使用的校验和算法。
    在检测过程中(下载的时候),找到的第一个校验和将被检测,然后就结束。这意外着如果你设置为"sha1, md5",那么如果ivy发现了一个sha1文件,它将使用这个sha1来比较下载文件的sha1,并且如果比较是通过的,ivy将认为这个文件是正确的。如果没有发现sha1文件,ivy将查找md5文件。如果没有发现任何一个,将不进行检测。
    在发布过程中,任何例举出来的校验和算法都将被计算和上传。

    默认的校验和算法是"sha1, md5"。
    如果你想修改这个默认值,你可以设置变量ivy.checksums。因此想使校验和验证失效,你仅仅需要设置ivy.checksums为""。


十. 事件和触发器

    从1.4版本之后,当ivy完成依赖的解析和一些其他任务,ivy将在最重要的步骤前后发出事件。你可以使用ivy的api来监听这些事件,或者你甚至可以注册一个触发器在特定事件发生时来执行特定的动作。

    这是尤其强大而灵活的特性,例如它容许在依赖解析前执行依赖的构建,或者在依赖解析过程中精确地追踪发生的事情。

    更多关于时间和触发器的细节,请看本文档的配置章节中的触发器文档页面。

十一. 循环依赖

    从1.4版本之后,循环依赖可以是直接或者间接。例如,如果A依赖A,这是循环依赖,如果A依赖B而B依赖A,这也是循环依赖。

    在ivy1.4之前循环依赖会导致viy产生错误。到ivy1.4止,当ivy发现循环依赖时的行为可以通过循环依赖策略来配置。

    3个内建的策略可用:

    * ignore/忽略
        循环依赖仅仅用详细的信息警告进行标志。
    * warn / 警告
        和忽略相同,除非它们被标识为警告(默认)
    * error / 错误
        发现循环依赖时终止依赖解析

    查看配置页面来看如果配置你想使用的循环依赖策略。

十二. 缓存和变更管理

    ivy非常依赖本地缓存来避免过于频繁的访问远程仓库,从而节约网络带宽和时间。

1) 缓存类型

    ivy缓存由两个不同部分组成:

    * 仓库缓存
        仓库缓存是ivy保存从模块仓库下载的数据的地方,和一些关系到这些制品的元信息在一起,和他们的原始位置一样。

    * 解析缓存
    这个部分的缓存用来保存被ivy用来重用解析过程的结果的解析数据。
    这个部分的缓存每次完成一次新的解析时都被覆盖,并且决不能被多进程同时使用。

    通常只有一个解析缓存,但是你可以定义多个仓库缓存,每个解析器可以使用单独的缓存。

2) 变更管理

    为了加快依赖解析和缓存使用的方法,ivy默认认为修订本从不修改。因此一旦ivy在它的缓存中有这个模块(元数据或者制品),ivy信任缓存,甚至不再查询仓库。大多数情况下这个优化时非常有用的,并且只要你遵循这个规范就不会引起问题: 修订本从不变更。除性能之外,还有几个好的原因来遵循这个原则。

    无论如何,取决于你当前的构建系统和你的依赖管理策略,你可能更愿意更新你的模块。有两种变更需要考虑:


    2.1) 模块元数据变更

    模块提供者不考虑经常优化模块元数据,他们更多的关注他们的api或者行为(如果他们甚至提供模块元数据)。我们不喜欢的事情经常发生:我们不得不更新模块元数据,一个依赖被遗忘了,或者另一个丢失了......

    在这种情况下,在你的依赖解析器上设置checkModified为"true"将是一个解决方案。这个标记告诉ivy需要检查模块的元数据相比较缓存是否被修改. ivy首先检查仓库中元数据的最后修改时间以决定只在必要时下载它,同样只在需要时更新它。


    2.2) 制品变更

    一些用户,尤其是从maven2过来的用户,喜欢使用一个特别的修订版本来处理经常变更的模块。在maven2中这个通常被称为SNAPSHOT(快照) 版本,并且有一种主张认为这样可以帮助节约空间,因为只需要为开发时可能创建的大量的中间产物保留一个修订版本。

    ivy使用"changing revision"的概念来支持这种方法。changing revision就是这样:一个ivy认为随着时间推移始终可能变更的修订版本.为了处理这个,可以通过使用以来标签明确指定一个依赖为可以变更,或者在解析器上使用changingPattern 和changingMatcher 属性来知名那个修订版本或者修订版本组可以被认为是变更的。

    一旦ivy知道一个修订版本是变更的,它将遵循这样的原则来避免过于频繁的检查仓库:如果模块的元数据没有修改,它将认为整个模块(包括制品)没有修改。即使如果模块描述符文件已经修改,它将检查模块的发行数据来看这个是不是同一个修订版本的一个新的发行。然后如果发行数据被修改了,它将检查制品的最后修改时间戳,并相应的下载它们。

    因此如果你想使用变更修订版本,使用发布任务来发布你的模块,请小心更新发布数据,然后一切都会工作的很好。并且记住也要将你的解析器设置checkModified=true"。


十三. 路径处理

    作为一个依赖管理器,ivy有一系列的文件相关操作,大部分使用路径或者路径模式来在文件系统上定位文件。

    这些路径可以明确是的相对路径或者绝对路径。我们推荐经常使用绝对路径,这样你不必担心你的相对路径的基准路径是什么。ivy提供一些变量,可以被用来作为你的绝对路径的基准路径。例如,ivy有基准路径的概念,这个基本和ant一致。你可以使用变量ivy.basedir来访问这个基准目录。因此如果你有类似这样的路径:

${ivy.basedir}/ivy.xml

    你就得到了一个绝对路径。在设置文件中,你同样有一个名为ivy.settings.dir的变量指向你的设置文件所在的目录,这使得定义和这个目录相关的路径变得非常容易。

    如果你真的想使用相对路径,被用于实际定位文件的基准路径取决于相对路径在哪里被定义:

    * 在ivy文件中,路径是相对于ivy文件自身(在ivy文件中唯一可能的路径是用于配置包含申明)。
    * 在设置文件中,用于文件包含的路径(也就是属性文件装载和设置文件包含)是相对于设置文件所在的目录。所有其他路径除非明确记录否则必须是绝对路径。
    * 在ivy的ant任务和ivy参数或选项中,路径是相对于ivy基准路径的,当在ant中调用时这个路径就是ant的basedir路径一致。
    

posted on 2009-07-08 14:26  CodingME!  阅读(4734)  评论(0编辑  收藏  举报

导航

Blog