Gradle - 从Artifactory

时间:2015-07-14 19:08:58

标签: gradle download artifactory artifact gradle-2

我使用Gradle构建项目(Java)。

Gradle 2.3,Java7 / 8。效果很好。

要构建项目,我们在编译,测试(testRuntime)和运行时阶段定义所需的所有库,并在依赖项部分中定义所有这些库,如:

dependencies {
    compile 'some_groupID:some_artifactID:some_version_x.y.z@ext_if_any'

    testRuntime 'SomeOtherOrSame_groupID:some_other_or_same_artifactID:some_version_x.y.z@ext_if_any'

    runtime 'SomeOtherOrSame_groupID:some_other_or_same_artifactID:some_version_x.y.z@ext_if_any'

}

我们的app / service运行构建/测试/ IT测试等所需的所有库(在运行时)的依赖项部分中有多个这样的条目。

Gradle到目前为止工作良好并从Artifactory下载所有工件。

我正在开发一个项目,我需要获取一个工件的所有版本(依赖项部分中的所有版本),对于单个groupID:artifactID only)即我想要以下.jar(默认扩展名)并创建一个包含所有版本化.jars的zip文件:

compile 'my.company.com:cool_library:1.0.0'
compile 'my.company.com:cool_library:1.0.1'
compile 'my.company.com:cool_library:1.1.0'
compile 'my.company.com:cool_library:1.2.0'

runtime 'my.company.com:another_cool_library:1.0.0'
runtime 'my.company.com:another_cool_library:1.2.0'
runtime 'my.company.com:cool_library:1.0.1'

我知道如何在Gradle中创建一个.zip文件(这很简单),但是Gradle没有从Artifactory或从给定的二进制存储库系统获取/下载所有.jar(对于我上面列出的每个版本)。 / p>

它只获得最新的(即cool_service-1.2.0.jar)。 Gradle做得很好,因为这样你就不会在来自同一个项目(cool_library)的类路径中有重复的类,并且因为它在依赖项部分中提到了不同的版本。

有人会说,为什么在cool_library版本1.2.0中有最新/最好的代码时我需要OLDER版本,如果一个使用这个库的项目需要它,只要说我想要 my.company .com:cool_library:1.2.0 并完成它或获得您想要编译的任何单个版本。就我而言,DEV团队编写了应用程序代码,他们在这里定义了cool_library-1.0.0.jar,但在其他地方定义了cool_library-1.2.0.jar。基本上,我需要开发人员在build.gradle文件中定义的所有内容。

如何创建一个custom_zip.zip文件,该文件将包含我在“编译”标题的依赖项部分中提到的所有cool_library-x.y.z.jar文件。

感谢。

2 个答案:

答案 0 :(得分:2)

我有一个gradle项目,我用它将特定的依赖项发布下载到一个目录中,然后我会上传到我们的本地IVY仓库,以便我们控制并提供特定版本的软件,以防它们消失。

它的主旨是使用ant.retrieve将文件从外部存储库中拉出来,然后再将其放入目录中,然后按照自己的意愿使用它们。

这不是完整的脚本,但我希望它足够有效。 Ant将使用ivy-cache dir作为缓存,并使用你的“回购”。包含所有jar文件的内容将在ivy-repo目录中。您可以调整antRetrieve任务以展平文件结构(更改模式变量),并根据需要删除ivy / src文件,但我会按照我的说明向您展示脚本:

project.ext.REPO_DOWNLOADER_DIR = "ivy-repo"
project.ext.IVY_SETTINGS = 'ivy-settings.xml' 
project.ext.IVY_CACHE = file('ivy-cache')

dependencies {
    compile ':ivy:2.3+'
}

def antRetrieve(dep) {
    // in each of the following patterns, the file will be downloaded with the [name] values filled in correctly,
    // e.g. from ant:retrieve(..."src,source"), the [type] will be either "src" or "source" depending on which was available to download.
    def jarPattern = "$REPO_DOWNLOADER_DIR/[organisation]/[revision]/[module]/[type]s/[artifact]-[revision].[ext]"
    def srcPattern = "$REPO_DOWNLOADER_DIR/[organisation]/[revision]/[module]/[type]s/[artifact]-[revision](-[classifier]).[ext]"
    def docPattern = "$REPO_DOWNLOADER_DIR/[organisation]/[revision]/[module]/[type]s/[artifact]-[revision](-[classifier]).[ext]"
    def ivyPattern = "$REPO_DOWNLOADER_DIR/[organisation]/[revision]/[module]/ivy.xml"
    def (org, module, rev) = dep.split(':')

    println "retrieving $org:$module:$rev"

    ant.retrieve(inline: "true", type: "jar,bundle", transitive: "true", pattern: "$jarPattern", ivypattern: "$ivyPattern", organisation: "$org", module: "$module", revision: "$rev", conf: "runtime,default")
    ant.retrieve(inline: "true", type: "src,source,sources", transitive: "true", pattern: "$srcPattern", organisation: "$org", module: "$module", revision: "$rev", conf: "sources")
    ant.retrieve(inline: "true", type: "doc,docs,javadoc,javadocs", transitive: "true", pattern: "$docPattern", organisation: "$org", module: "$module", revision: "$rev", conf: "javadoc")

}

task retrieve << {
    ant.taskdef(resource: 'org/apache/ivy/ant/antlib.xml', classpath: configurations.compile.asPath)
    ant.properties['repo.downloader.cache'] = IVY_CACHE
    ant.settings(file: IVY_SETTINGS)

    if (project.hasProperty('modules')) {
        def moduleList = project.modules.split(',')
        moduleList.each { module ->
            antRetrieve(module)
        }
    }

    if (project.hasProperty("modfile")) {
        def modulesFile = file(project.modfile)
        if (! modulesFile.exists()) {
            throw new GradleException("Could not find specified modules file: $modulesFile")
        }
        modulesFile.eachLine { module ->
            antRetrieve(module)
        }
    }
}

然后,ivy-settings.xml文件设置您想要从中提取的外部存储库。根据您的需要添加任何其他内容(例如clojars for clojure jar):

<ivysettings>
    <settings defaultResolver="spring-chain" />
    <caches defaultCacheDir="${repo.downloader.cache}" />
    <resolvers>
        <chain name="spring-chain">
            <url name="com.springsource.repository.bundles.release">
                <ivy pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
                <artifact pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
            </url>
            <url name="com.springsource.repository.bundles.external">
                <ivy pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
                <artifact pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
            </url>
            <ibiblio name="ibiblio" m2compatible="true" />
            <ibiblio name="uk-maven" m2compatible="true" root="http://uk.maven.org/maven2"/>
        </chain>
    </resolvers>
</ivysettings>

您可以使用以下方法之一调用整个内容:

./gradlew retrieve -Pmodules='a:b:1.0,x:y:1.1'
./gradlew retrieve -PmodFile='/path/to/modlist.txt'

允许您将所有版本转储到文本文件中,或在命令行中指定它们。

这也会降低依赖性。它唯一没有做的是拉src文件的依赖(它为主命名存档),但我有一个shell脚本,只询问dirs寻找丢失的src并迭代retrieve任务那些作为主要条目,但如果你不是在消息来源之后,那么你应该没事。

如果你采用这种策略还有一些工作要做,但它会下载你想要的任何依赖项的所有文件,你可以根据需要将它们全部拉出来供你自己消费。以上仅适用于直接上传到本地常春藤仓库。

答案 1 :(得分:0)

使用这个伟大的工具,它是可能的。全部阅读(以不同的方式做事)。

链接 Gradle下载任务https://github.com/michel-kraemer/gradle-download-task

对于ex:在build.gradle中,您将拥有以下内容:

plugins {
    id "de.undercouch.download" version "1.2"
}

import de.undercouch.gradle.tasks.download.Download
apply plugin: 'java'
apply plugin: 'de.undercouch.download'


repositories {
  maven {
    url "http://yourartifatory:1020/artifactory/virtual-repos"
  }
}

//Lets says, I want to download my.company.com:CoolServices:1.0 jar or any extension file
//Then I can create a list and specify what all I need as:
def deps = [
            [ "my/company/com", "CoolServices", "1.0", "jar" ],
            [ "my/company/com", "CoolServices", "1.1", "jar" ],
            [ "my/company/com", "CoolServices", "1.2", "jar" ]
           ]

task downloadArts << {
     //Iterate over each dependencies as per the list
     deps.each { groupId, artifactId, version, extn ->
          download {
              src "http://yourartifactory.fqdn.com:1020/artifactory/simple/some-physical-actual-repository-local/$groupId/$artifactId/$version/$artifactId-$version.$extn"
              dest buildDir
              //If you want the downloaded files inside build/xxx folder, create that xxx folder first outside of the clousure i.e. file("build/xxx").mkdir()
          }
     }
}


现在,运行“ gradle clean downloadArts ”,它将在 build build / xxx 文件夹中打印要下载/排队的内容在那里你可以找到所有下载的文件(你在deps列表变量中提到的.jar / etc扩展文件)。

您还可以使用它来推送依赖项部分以进行编译,运行时,testRuntime或根据需要创建custom_zip.zip文件。

例如:

dependencies {
    compile  fileTree( dir: "build", include: '*.*' )
    runtime  fileTree( dir: "build/xxx", include: '*.*' )
}

或者创建一个custom_zip.zip文件(包含所有下载的.jar / extension文件)。