如何在gradle插件中添加自定义依赖处理程序?

如何在gradle插件中添加自定义依赖处理程序?,gradle,Gradle,我想为gradle插件的用户提供一种添加所有必要依赖项的简单方法。类似于gradleApi()或localGroovy() 我发现gradleApi和localGroovy都是在DefaultDependencyHandler中定义和实现的。我可以提供一个Dependencyhandler的自定义实现,它扩展了我插件中的DefaultDependencyHandler?或者有没有更简单的方法来实现我想要的 提前服用thx。看看这是否有一定帮助。假设您创建了一个自定义插件/类,并使用它在Gradl

我想为gradle插件的用户提供一种添加所有必要依赖项的简单方法。类似于
gradleApi()
localGroovy()

我发现gradleApi和localGroovy都是在
DefaultDependencyHandler
中定义和实现的。我可以提供一个
Dependencyhandler
的自定义实现,它扩展了我插件中的
DefaultDependencyHandler
?或者有没有更简单的方法来实现我想要的


提前服用thx。

看看这是否有一定帮助。假设您创建了一个自定义插件/类,并使用它在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
    }
}
// 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
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
内置。渐变

// 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
    }
}
// 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
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-compile.txt中,您可以有如下条目

// 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
    }
}
// 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
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中,您可以有以下条目(并根据您想要的梯度阶段/功能创建类似的dep XXXX文件:编译、测试、war、执行某些操作等)。

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

一种解决方案是让插件在
dependencies
容器上安装一个额外的方法:

def jarDir = ...

project.dependencies.ext.pluginDeps = { 
    project.fileTree(jarDir) // filter file tree if necessary 
}
然后,用户可以执行以下操作:

dependencies {
    compile pluginDeps()
}
额外的属性/方法通常只能由构建脚本使用(因为它们没有可以发现和推理的模型作为支持),但在这种特殊情况下(从Gradle 2.1开始),我想不出更好的解决方案


PS:请记住,对于基于文件(而不是存储库)的依赖项,不会发生版本冲突解决。

我找到了另一种方法。您可以依靠约定机制来完成这项工作。首先定义一个约定类:

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 plugin: CustomDepsPlugin

dependencies {
    compile customDependency()
}

这种方法可以说更干净;它唯一的潜在缺点是约定对象有点“不推荐使用”,不建议使用。此外,它可能会导致Kotlin DSL出现问题(据我所知,Kotlin DSL并不真正支持约定对象);但是,如果您想支持Kotlin DSL,您可以将这些依赖项生成函数公开为可导入的顶级函数,并将它们导入到构建脚本。

您可以创建一个文本文件dep-compile.txt、dep-tests.txt或dep-war.txt等,其中每个文本文件都可以为ex:org.mockit:jmockit:1.7存储每行的依赖项(与编译或测试阶段需要junit的文件类型相对应)。现在,在build.gradle中,您可以使用一个自定义插件来读取这些.txt文件,并将每个条目添加到用户定义的列表中,例如:delListCompile、depListTest等。完成后,您可以拥有依赖项{compile dellistcile…testCompile depListCompile,depListTest…//etc}依赖项应该从Maven/Ivy存储库解析,还是已经存在于本地磁盘上?@PeterNiederwieser依赖项位于磁盘上。用户配置其本地安装的路径,我从相关文件夹收集jar文件。您可以使用文件或文件树(srcDir:“folder”,include:“*.jar”)要在依赖项{…}中获取它们进行编译、testXX等第.thx节中也有关于冲突解决的提示。不过,别指望这会是个问题。更让我困扰的是,没有附加源JAR。源JAR和Javadoc JAR仅在IDE中自动配置为存储库依赖项。很长一段时间以来,这只适用于Maven存储库,但到目前为止,它可能也会为
flatDir
存储库工作(有关
flatDir
的详细信息,请参阅),只要jar使用Maven文件名约定。我应该在
def jarDir=…
中的
中放置什么?jar文件的路径不起作用。相反,它显示了一个错误。