现在你已经看到从一个已经存在的仓库创建你自己的仓库是如何的简单,你可能会想知道如何处理更加复杂的情况,例如当源仓库和目的地仓库不遵循相同的命名约定。
1) 通往专业仓库之路
我们将学习这个如何构建一个专业仓库的章节。什么是专业仓库?我们的观点是一个良好质量的仓库必须遵循有关项目命名的清晰的规则,并必须提供正确,可用,可配置和验证过的项目描述符。为了达到这些目标,我们认为你必须构建你自己的仓库。
在前面的例子里面我们已经看到,我们可以使用一些公共仓库看来开始构建我们自己的仓库。然而,结果并不总是那么理想, 尤其是关系到使用的命名规则。
当你有一个已经存在的仓库并且希望从大量的不遵循相同的命名转换的公共仓库中获益时,这个问题非常常见。或者仅仅是因为你发现你作为基础使用的仓库不够一直- 为什么所有的apache commons模块不适用org.apache.commons 组织? 历史原因。但是如果你安装你自己的仓库,你可能不想从历史中蒙受损失。
幸运的是,对于这种问题ivy有一种非常强大的答复:namespaces.
2) 使用命名空间
当你查看前面教程构建的仓库时,你将清晰的看到我们正在谈论的东西:所有apache commons模块使用它们自己的名字作为组织。
因此让我们看一下通过使用namespaces ivy可以做什么(稍后我们将深入细节):
Z:\>ant commons-lang-1-0-ibiblio-with-namespace
Buildfile: build.xml
load-ivy:
init-ivy:
maven2-namespace:
[ivy:install] :: loading settings :: url = jar:file://home/xavier/.ivy2/jars/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:install] :: Ivy 2.0.0-beta1-local-20071130005044 - 20071130005044 :: http://ant.apache.org/ivy/ ::
:: loading settings :: file = /home/xavier/ivy/settings/ivysettings-advanced.xml
[ivy:install] :: installing apache#commons-lang;1.0 ::
[ivy:install] :: resolving dependencies ::
[ivy:install] found apache#commons-lang;1.0 in libraries
[ivy:install] :: downloading artifacts to cache ::
[ivy:install] downloading http://repo1.maven.org/maven2/commons-lang/commons-lang/1.0/commons-lang-1.0.jar ...
[ivy:install] ........ (62kB)
[ivy:install] .. (0kB)
[ivy:install] [SUCCESSFUL ] apache#commons-lang;1.0/commons-lang.jar[jar] (1612ms)
[ivy:install] :: installing in my-repository ::
[ivy:install] published commons-lang to /home/xavier/ivy/myrepository/advanced/apache/commons-lang/jars/commons-lang-1.0.jar
[ivy:install] published ivy to /home/xavier/ivy/myrepository/advanced/apache/commons-lang/ivys/ivy-1.0.xml
[ivy:install] :: install resolution report ::
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 1 | 1 | 0 | 0 || 1 | 1 |
---------------------------------------------------------------------
BUILD SUCCESSFUL
Total time: 3 seconds
现在我们看一下我们的仓库,它看上去很好。
Z:\>dir /s /B /A:-D myrepository\advanced
Z:\myrepository\advanced\apache\commons-lang\ivys\ivy-1.0.xml
Z:\myrepository\advanced\apache\commons-lang\ivys\ivy-1.0.xml.md5
Z:\myrepository\advanced\apache\commons-lang\ivys\ivy-1.0.xml.sha1
Z:\myrepository\advanced\apache\commons-lang\jars\commons-lang-1.0.jar
Z:\myrepository\advanced\apache\commons-lang\jars\commons-lang-1.0.jar.md5
Z:\myrepository\advanced\apache\commons-lang\jars\commons-lang-1.0.jar.sha1
我们甚至可以看一下我们仓库中的commons-lang ivy文件:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="1.0">
<info organisation="apache"
module="commons-lang"
revision="1.0"
status="integration"
publication="20051124062021"
namespace="ibiblio-maven2"
/>
......
很好,我们看到组织现在是'apache'。但是ivy是从哪里获得这个的呢?
1. 这是如何工作的?
实际上ivy和以往一样使用同样的仓库作为源仓库,仅仅有一点不同:namespace参数。
<ibiblio name="libraries"
root="${ibiblio-maven2-root}"
m2compatible="true"
namespace="maven2"
/>
namespace由一系列规则定义而成。这些规则基于正则表达式,并告诉ivy如何从仓库命名空间转换数据到系统命名空间,换言之,ivy时常运行的命名空间(例如ivy 缓存通常使用系统命名空间).
对于我们调用maven2的命名空间,我们已经定义了一些规则,这里是一个:
处理导入apache maven1项目的规则
<rule> <!-- imported apache maven1 projects -->
<fromsystem>
<src org="apache" module=".+"/>
<dest org="$m0" module="$m0"/>
</fromsystem>
<tosystem>
<src org="commons-.+" module="commons-.+" />
<src org="ant.*" module="ant.*" />
...
<src org="xmlrpc" module="xmlrpc" />
<dest org="apache" module="$m0"/>
</tosystem>
</rule>
理解命名空间:
(1) fromsystem : 在这里我们定义,在系统命名空间中以组织"apache"定义的项目被转换为目的地命名空间中使用模块名为组织的项目,无论修订版本是什么.例如,系统命名空间中的项目apache#commons-lang;1.0奖被转换为maven2解析器命名空间中的commons-lang#commons-lang;1.0。
(2) tosystem : 在这里我们定义反向映射,换言之从maven2仓库转换apache项目到系统命名空间的apache项目。这里使用的规则告诉说所有组织名匹配commons-.+ (把它看成java正则表达式)项目被转换为组织是apache而模块名还是原来的项目。同样的规则被使用到其他apache项目例如ant等等。
注意正则表达式的用法:为了识别在组织,模块和修订版本中找到的正则表达式, 使用的表示法用字母'o', 'm' 和'r'作为匹配的正则表达式的前缀。
$o0 : 在组织属性中完全匹配的值
$o1 : 在组织属性中标记的第一个匹配的语法分组
...
同样应用在模块中: $m0, $m1, ...
也用于修订版本 : $r0, $r1, ...
好了,现在你知道命名空间背后的想法了,现在你可以检查例子中提供的整个命名空间的设置,并使用命名空间测试模块和它的依赖的安装。
运行
ant maven2-namespace-deps
然后你将看到结果仓库比我们第一次构件的清晰了。
从我们的经验来看,创建命名空间的花费是值得的,如果你经常需要在你自己的仓库中,这里命名规则已经存在或者更加严格,为第三方类库增加新的模块或者修订版本。