我想为gradle插件的用户提供添加所有必需依赖项的简单方法。像gradleApi()
或localGroovy()
之类的东西。
我发现gradleApi和localGroovy都在DependencyHandler
中定义并在DefaultDependencyHandler
中实现。我可以在我的插件中提供Dependencyhandler
的自定义实现,扩展DefaultDependencyHandler
吗?或者是否有更简单的方法来实现我想要的目标?
答案 0 :(得分:10)
一种解决方案是让插件在dependencies
容器上安装额外的方法:
def jarDir = ...
project.dependencies.ext.pluginDeps = {
project.fileTree(jarDir) // filter file tree if necessary
}
用户可以这样做:
dependencies {
compile pluginDeps()
}
额外的属性/方法通常仅用于构建脚本(因为它们不受可以发现和推理的模型的支持),但在这种特殊情况下(从Gradle 2.1开始)我无法想出一个明显更好的解决方案。
PS:请记住,对于基于文件(而非基于存储库)的依赖项,不会发生版本冲突解决。
答案 1 :(得分:0)
看看这在某种程度上是否有帮助。我们假设您创建了一个自定义插件/类并使用它在Gradle中的工件(在GRADLE_HOME / init.d / common.gradle文件级别内)。
自定义插件项目的java / groovy文件看起来像
// Your custom plugin class file will look like
// Your custom plugin's source code will reside at: com.mycustom.plugin.gradle under src/main/java folder tree.
package com.mycustom.plugin.gradle
import org.gradle.api.*
import org.gradle.api.file.*
import java.io.File;
public class myCustomFileUtil {
/**
* Default constructor
*/
public myCustomFileUtil() {
}
/**
* Read file returning list of lines. Double slash (//) at start of line
* defines a comment.
* @param fileName File to read.
* @return List of lines.
*/
public static List readIntoList( String fileName ) {
def fname = new File( fileName )
def listFinal = []
def listLines = fname.readLines()
listLines.each { it ->
def str = it.trim();
if( str.length() > 0 ) {
if( ! str.startsWith( "//" ) ) listFinal.add( str );
}
}
return listFinal
}
}
在build.gradle中
// The following funcationality is coming from a custom plugin that you'll write which will read a text file and create a list.
// It'll also ignore any lines that start with "//"
import com.mycustom.plugin.gradle.myCustomFileUtil
sourceSets {
//if you have any
//main
//test
//acceptanceTest
//etc
}
// Read dependency lists from external files
List depListCompile = myCustomFileUtil.readIntoList( "$projectDir/dep-compile.txt" )
List depListTest = myCustomFileUtil.readIntoList( "$projectDir/dep-testArtifacts.txt" )
List depListWar = myCustomFileUtil.readIntoList( "$projectDir/dep-war.txt" )
List depListJibx = myCustomFileUtil.readIntoList( "$projectDir/dep-jibx.txt" )
List depListSomeOperationINeed = myCustomFileUtil.readIntoList( "$projectDir/dep-someoperationineed.txt" )
// Define dependencies
dependencies {
// Compilation
compile depListCompile
// If dependencies already exist on the local folder / in some workspace
compile fileTree(srcDir: "somefolder/whichcontain/myjar", include: "*.jar")
compile fileTree(srcDir: "/path/xx/yy/somefolder/whichcontain/myotherartifacts", include: "*.[zw]*")
compile fileTree(srcDir: "C:/zzz/somefolder/whichcontain", include: "myotherartifacts/*.[pj]*")
// Unit Tests
testCompile depListTest
// Acceptance tests
// Everything from compile and testCompile targets
acceptanceTestCompile configurations.compile
acceptanceTestCompile configurations.testCompile
// Output of compiling "main" files
acceptanceTestCompile sourceSets.main.output
// Additional dependencies from war and others
acceptanceTestCompile depListTest, depListWar
// All configuration files
acceptanceTestRuntime files( 'conf' )
}
// ... and more code here to do other operations
在dep-compile.txt中,您可以输入
等条目com.mycompany.project:oneofmycompanyartifact1:1.1.1
com.mycompany.project:oneofmycompanyartifact2:1.0.1@zip
httpunit:httpunit:1.6
jibx:jibx-bind:0.10.3.3
jibx:jibx-extras:0.10.3.3
jibx:jibx-run:0.10.3.3
cactus:cactus:1.7.2
selenium:selenium:0.9.2
同样,在dep-testArtifacts.txt中,您可以拥有以下条目(并根据所需的Gradle阶段/功能创建类似的dep-XXXX文件:compile,test,war,doingSomeOperation等)。
cactus:cactus:1.7.2
jackson-all:jackson-all:1.9.9
jibx:jibx-bind:0.10.3.3
jibx:jibx-extras:0.10.3.3
jibx:jibx-run:0.10.3.3
//junit:junit:4.10
junit:junit:4.11
mockito-all:mockito-all:1.9.5
答案 2 :(得分:0)
我找到了另一种方法。您可以依靠约定机制来做到这一点。首先定义一个约定类:
class CustomDepsPluginConvention {
// here you can return anything which configuration methods in the
// `dependencies` block would accept, e.g. a string or a map
fun customDependency(): Map<String, String> {
return mapOf(
"group" to "com.whatever",
"name" to "whatever",
"version" to "1.2.3"
)
}
}
然后使用插件apply()
方法将此约定对象添加到项目中:
open class CustomDepsPlugin : Plugin<Project> {
override fun apply(project: Project) {
// the identifier of the convention object does not matter,
// as long as it is unique
project.convention.plugins["customDeps"] = CustomDepsPluginConvention()
}
}
应用此插件后,约定对象将被添加到项目对象,将其所有方法和属性公开在项目对象上,从而使它们可直接在构建脚本中使用:
apply plugin: CustomDepsPlugin
dependencies {
compile customDependency()
}
可以说这种方法更清洁;唯一的潜在缺点是约定对象已被“弃用”,不建议使用。同样,这可能会导致Kotlin DSL出现问题(据我所知,Kotlin DSL并不真正支持约定对象);但是,如果您想支持Kotlin DSL,则可以将这些依赖关系生成功能公开为可导入的顶级功能,并将其导入到您的构建脚本中。