本文介绍了从Gradle自定义插件中的某些依赖中剥离版本号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个自定义插件,我们希望在其中构建用于部署的特殊tar文件。我们想在某些依赖项上剥离版本号。

We have a custom plugin where we would like to build a special tar file used for deployment. We would like to strip the version number on certain dependencies.

插件代码:

void addTarTask(Project project) {
    Tar tar = project.tasks.create("tar", Tar)
    tar.classifier = "bin"
    project.afterEvaluate {
        tar.into("${project.name}-${project.version}"){
            into('lib'){
                from project.tasks.jar
                from project.configurations.runtime 
            }

            //snip more custom requirements
        }
    }
}

我尝试了一些使用正则表达式从文件中删除版本的操作-

I have tried something where we use a regex to remove the version from the file - like this:

into('lib'){
    from project.tasks.jar
    from project.configurations.runtime {
        rename '(.*)-[0-9]+\\..*.jar', '$1.jar' // not sure regex is okay - it is just to demo
    }
}

不是p可以获取类型依赖项/工件对象,因此我可以跳过正则表达式并使代码更简洁。类似于(pseducode):

Is it not possible to get a type dependency/artifact object so i can skip the regex and make the code more clean. Something like (pseducode):

if(${artifact.extension} == "so") {
    return ${artifact.name}.${artifact.extension}
} else {
    // just return normal file
}

感谢您的帮助:-)

推荐答案

运行时 您引用的具有依赖项属性,该属性是保持对象。
这意味着您可以遍历依赖项以获取其名称。
您可以使用它来编写特定的重命名规则。还有一些注意事项。

The runtime Configuration you are referencing has an dependencies property that is a DependencySet holding Dependency objects.That means you can iterate trough the dependencies to to get their name.You can use that to write specific rename rules. There's also some caveats to consider.

我生成了一个示例项目来举例说明:

I generated a sample project to exemplify with:

gradle init --type java-library

然后将build.gradle编辑为:

Then edited build.gradle to:

apply plugin: 'java'

repositories {
    jcenter()
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.21'
    testCompile 'junit:junit:4.12'
}

task log << {
    configurations.runtime.allDependencies.each { println it }
    println ""
    configurations.testCompile.allDependencies.each { println it }
}

task copy(type: Copy) {
    from configurations.runtime
    into  "$buildDir/lib"
    configurations.runtime.allDependencies.each {
        rename "-${it.version}", ""
    } 
}

结果:

[:~/tmp] % ./gradlew log copy
:log
DefaultExternalModuleDependency{group='org.slf4j', name='slf4j-api', version='1.7.21', configuration='default'}

DefaultExternalModuleDependency{group='junit', name='junit', version='4.12', configuration='default'}
DefaultExternalModuleDependency{group='org.slf4j', name='slf4j-api', version='1.7.21', configuration='default'}
[...]

[:~/tmp] % ./gradlew dependencies    
[...]
testCompile - Dependencies for source set 'test'.
+--- org.slf4j:slf4j-api:1.7.21
\--- junit:junit:4.12
     \--- org.hamcrest:hamcrest-core:1.3

[...]

[:~/tmp] % ls build/lib
slf4j-api.jar

请注意, hamcrest 依赖项由 gradle依赖项显示,但未打印出来。这是因为在配置时尚未解决依赖性,因此gradle尚不知道传递性依赖性。换句话说,您可以在插件中实现类似于上面的复制任务的操作,但是它仅适用于直接在构建脚本中指定的依赖项。当然,如果您必须重命名其中的一些,您也可以显式地指定传递依赖,它仍然可以使用。由于遵循 extendsFrom 规则,因此testCompile配置可以正确打印slf4j和junit。

Note that the hamcrest dependency is shown by gradle dependencies but it's not printed. This is because the dependencies are not resolved at configuration time, so gradle does not yet know about the transitive dependencies. In other words you can implement something like the copy task above in your plugin but it will only work for the dependencies you specify directly in your build script. Of course you could specify the transitive dependencies explicitly too if you have to rename some of those and it will still work. The testCompile configuration correctly prints both slf4j and junit because the extendsFrom rules are followed.

这篇关于从Gradle自定义插件中的某些依赖中剥离版本号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 16:10