英文原文:
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文件参考的冲突章节。