Apache的常春藤:常春藤依赖文件 [英] Apache Ivy: Dependency Ivy FIles

查看:189
本文介绍了Apache的常春藤:常春藤依赖文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Threequick关于Apache的常青藤问题:

Threequick questions regarding Apache Ivy:

(1)纵观我们的项目,我们使用超过100个共同的JAR文件(log4j的,JUnit中,公地CLI等)。我们是否有写的ivy.xml(模块描述符)文件所有的人,还是有通用的人,我可以在ibiblio上(或其他)回购找?要强制用户为每个依赖听起来pretty残酷和不寻常的给我写自己的ivy文件。

(1) Throughout our projects, we use over 100 "common" JARs (log4j, junit, commons-cli, etc.). Do we have to write the ivy.xml ("module descriptor") files for all of them, or are there generic ones I can find in the ibiblio (or other) repo? To force your users to write their own ivy files for each dependency sounds pretty cruel and unusual to me.

(2)甚至需要用于特定的JAR常春藤文件,或根本常春藤具有用于当它看起来在一个回购为不具有相应的常春藤文件依赖关系默认?

(2) Are ivy files even required for a particular JAR, or does Ivy have defaults for when it looks in a repo for a dependency that doesn't have a corresponding ivy file?

(3)是否有可能有我的所有依赖一个文件夹(回购),并定义配置所有的人都在里面1 ivy.xml文件?

(3) Is it possible to have all my dependencies in one folder (repo) and define 1 ivy.xml file that configures all of them inside it?

感谢这里的任何帮助!

推荐答案

(1)常青藤文件没有列出每一个罐子。一些罐子是别人的依赖,并自动从资料库常春藤拉。没有默认值都可用。对于一个新的项目,我通常生成我的第一个ivy文件(见附件ant2ivy脚本)

(1) Ivy files do not have to list every single jar. Some jars are dependencies of others and automatically pulled by ivy from the repository. No defaults are available. For a new project I normally generate my first ivy file (see the attached ant2ivy script)

(2)ivy文件时,才需要在常春藤库时,罐子有依赖关系。话说回来,这是很好的做法有一个。我个人欺骗和使用Maven仓库管理如的Nexus 来存储我的罐子。

(2) An ivy file is only required in an ivy repository when the jar has dependencies. Having said that it's good practice to have one. Personally I cheat and use a Maven repository manager like Nexus to store my jars.

(3)您可以在您的设置文件遵循建立文件系统解析本地资源库:

(3) You can create a local repository using the filesystem resolver as follows in your settings file:

<ivysettings>
  <settings defaultResolver='maven-repos' />
  <resolvers>
    <chain name='maven-repos'>
      <ibiblio name='central' m2compatible='true' />
      <ibiblio name='spring-external' m2compatible='true' root='http://repository.springsource.com/maven/bundles/external' />
    </chain>
    <filesystem name='local'>
      <artifact pattern='/home/mark/tmp/petclinic/build/jars/[artifact]' />
    </filesystem>
  </resolvers>
  <modules>
    <module organisation='NA' name='mylibrary1.jar' resolver='local' />
    <module organisation='NA' name='mylibrary2.jar' resolver='local' />
    ..
  </modules>
</ivysettings>

在与模块相结合的声明这使得以下可能在您的的ivy.xml 文件:

When combined with the module declarations this makes the following possible in your ivy.xml file:

   <dependency org='NA' name='mylibrary1.jar' rev='NA' />
   <dependency org='NA' name='mylibrary2.jar' rev='NA' />

所有其他依赖从Maven仓库中检索。

All other dependencies are retrieved from Maven repositories.

如果您以下的逻辑连接我的 ant2ivy 的脚本,你会看到我用这个战略,我无法确定使用Sonatype的存储库中REST API的罐子

If you following the logic of my attached ant2ivy script you'll see I use this strategy with the jars I cannot identify using Sonatype's repository REST API

这是执行Sonatypes仓库的查询,以确定一个指定的目录罐子粗略的Groovy脚本

This is a rough and ready groovy script that performs a lookup of Sonatypes repository to identify jars in a specified directory

//
// Dependencies
// ============

import groovy.xml.MarkupBuilder

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Grapes([
    @Grab(group='org.slf4j', module='slf4j-simple', version='1.6.2') 
])

//
// Classes
// =======

class Ant2Ivy {

    Logger log = LoggerFactory.getLogger(this.class.name);
    String groupId
    String artifactId
    String repoUrl

    Ant2Ivy(groupId, artifactId) {
        this(groupId, artifactId, "http://repository.sonatype.org")
    }

    Ant2Ivy(groupId, artifactId, repoUrl) {
        this.groupId = groupId
        this.artifactId = artifactId
        this.repoUrl = repoUrl

        log.debug "groupId: {}, artifactId: {}", groupId, artifactId
    }

    //
    // Given a directory, find all jar and search Nexus
    // based on the file's checksum
    //
    // Return a data structure containing the GAV coordinates of each jar
    //
    def search(File inputDir) {
        def results = [:]
        results["found"] = []
        results["missing"] = []

        log.info "Searching: {} ...", repoUrl

        def ant = new AntBuilder()
        ant.fileset(id:"jars", dir:inputDir.absolutePath, includes:"**/*.jar")

        ant.project.references.jars.each {
            def jar = new File(inputDir, it.name)

            // Checksum URL
            ant.checksum(file:jar.absolutePath, algorithm:"SHA1", property:jar.name)

            def searchUrl = "${repoUrl}/service/local/data_index?sha1=${ant.project.properties[jar.name]}"
            log.debug "SearchUrl: {}, File: {}", searchUrl, jar.name

            // Search for the first result
            def searchResults = new XmlParser().parseText(searchUrl.toURL().text)
            def artifact = searchResults.data.artifact[0]

            if (artifact) {
                log.debug "Found: {}", jar.name
                results["found"].add([file:jar.name, groupId:artifact.groupId.text(), artifactId:artifact.artifactId.text(), version:artifact.version.text()])
            }
            else {
                log.warn "Not Found: {}", jar.name
                results["missing"].add([file:jar.name, fileObj:jar])
            }
        }

        return results
    }

    //
    // Given an input direcory, search for the GAV coordinates 
    // and use this information to write two XML files:
    //
    // ivy.xml          Contains the ivy dependency declarations
    // ivysettings.xml  Resolver configuration
    //
    def generate(File inputDir, File outputDir) {
        outputDir.mkdir()

        def antFile = new File(outputDir, "build.xml")
        def ivyFile = new File(outputDir, "ivy.xml")
        def ivySettingsFile = new File(outputDir, "ivysettings.xml")
        def localRepo = new File(outputDir, "jars")
        def results = search(inputDir)

        //
        // Generate the ant build file
        //
        log.info "Generating ant file: {} ...", antFile.absolutePath
        def antContent = new MarkupBuilder(antFile.newPrintWriter())

        antContent.project(name: "Sample ivy builde", default:"resolve", "xmlns:ivy":"antlib:org.apache.ivy.ant" ) {
            target(name:"resolve") {
                "ivy:resolve"()
            }
            target(name:"clean") {
                "ivy:cleancache"()
            }
        }

        // 
        // Generate the ivy file
        //
        log.info "Generating ivy file: {} ...", ivyFile.absolutePath
        def ivyConfig = new MarkupBuilder(ivyFile.newPrintWriter())

        ivyConfig."ivy-module"(version:"2.0") {
            info(organisation:this.groupId, module:this.artifactId) 
            configurations(defaultconfmapping:"default")
            dependencies() {
                results.found.each {
                    dependency(org:it.groupId, name:it.artifactId, rev:it.version, conf:"default->master")
                }
                results.missing.each {
                    dependency(org:"NA", name:it.file, rev:"NA")
                }
            }
        }

        // 
        // Generate the ivy settings file
        //
        log.info "Generating ivy settings file: {} ...", ivySettingsFile.absolutePath
        def ivySettings = new MarkupBuilder(ivySettingsFile.newPrintWriter())
        def ant = new AntBuilder()

        ivySettings.ivysettings() {
            settings(defaultResolver:"maven-repos") 
            resolvers() {
                chain(name:"maven-repos") {
                    // TODO: Make this list of Maven repos configurable
                    ibiblio(name:"central", m2compatible:"true")
                    ibiblio(name:"spring-external", m2compatible:"true", root:"http://repository.springsource.com/maven/bundles/external")
                }
                if (results.missing.size() > 0) {
                    filesystem(name:"local") {
                        artifact(pattern:"${localRepo.absolutePath}/[artifact]")
                    }
                }
            }
            if (results.missing.size() > 0) {
                modules() {
                    results.missing.each {
                        module(organisation:"NA", name:it.file, resolver:"local")
                        ant.copy(file:it.fileObj.absolutePath, tofile:"${localRepo.absolutePath}/${it.file}")
                    }
                }
            }
        }
    }
}

// 
// Main program
// ============
def cli = new CliBuilder(usage: 'ant2ivy')
cli.with {
    h longOpt: 'help', 'Show usage information'
    g longOpt: 'groupid',    args: 1, 'Module groupid', required: true
    a longOpt: 'artifactid', args: 1, 'Module artifactid', required: true
    s longOpt: 'sourcedir',  args: 1, 'Source directory containing jars', required: true
    t longOpt: 'targetdir',  args: 1, 'Target directory where write ivy build files', required: true
}

def options = cli.parse(args)
if (!options) {
    return
}

if (options.help) {
    cli.usage()
}

// 
// Generate ivy configuration
//
def ant2ivy = new Ant2Ivy(options.groupid, options.artifactid)
ant2ivy.generate(new File(options.sourcedir), new File(options.targetdir))

脚本运行如下:

groovy ant2ivy.groovy -g com.hello -a test -s targetdir/WEB-INF/lib -t build

在对运行的PetClinic 品尝它产生以下文件

When run against the petclinic sample it produced the following files

build/build.xml
build/ivy.xml
build/ivysettings.xml
build/jars/..
..

罐子目录包含不可能在一个Maven回购找到这些库。

The jars directory contains those libraries which could not be found in a Maven repo.

这篇关于Apache的常春藤:常春藤依赖文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆