如何在build.gradle中定义和调用自定义方法?
How to define and call custom methods in build.gradle?
作为我项目的一部分,我需要从目录中读取文件并在构建脚本中执行所有这些操作。对于每个文件,操作都是相同的(读取一些 SQL 查询并执行)。我认为这是一项重复性任务,最好在方法中编写。由于我是 Gradle 的新手,所以我不知道它应该如何。请帮忙。
下面给出了一种方法:
ext.myMethod = { param1, param2 ->
// Method body here
}
请注意,这是为项目范围创建的,即。对项目全局可用,可以在构建脚本的任何地方使用 myMethod(p1, p2)
如下调用,相当于 project.myMethod(p1, p2)
该方法也可以在不同的范围内定义,例如在任务内:
task myTask {
ext.myMethod = { param1, param2 ->
// Method body here
}
doLast {
myMethod(p1, p2) // This will resolve 'myMethod' defined in task
}
}
您可以通过以下方式定义方法:
// Define an extra property
ext.srcDirName = 'src/java'
// Define a method
def getSrcDir(project) {
return project.file(srcDirName)
}
您可以在 gradle 文档中找到更多详细信息 Chapter 62. Organizing Build Logic
如果您在任何其他文件中定义了任何方法 *.gradle - ext.method() 使其可在项目范围内访问。例如这里是
versioning.gradle
// ext makes method callable project wide
ext.getVersionName = { ->
try {
def branchout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
standardOutput = branchout
}
def branch = branchout.toString().trim()
if (branch.equals("master")) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
return stdout.toString().trim()
} else {
return branch;
}
}
catch (ignored) {
return null;
}
}
build.gradle
task showVersion << {
// Use inherited method
println 'VersionName: ' + getVersionName()
}
没有 ext.method() 格式,该方法将仅在声明的 *.gradle 文件中可用。这与属性相同。
一个包含方法的根对象示例。
hg.gradle 文件:
ext.hg = [
cloneOrPull: { source, dest, branch ->
if (!dest.isDirectory())
hg.clone(source, dest, branch)
else
hg.pull(dest)
hg.update(dest, branch)
},
clone: { source, dest, branch ->
dest.mkdirs()
exec {
commandLine 'hg', 'clone', '--noupdate', source, dest.absolutePath
}
},
pull: { dest ->
exec {
workingDir dest.absolutePath
commandLine 'hg', 'pull'
}
},
]
build.gradle 文件
apply from: 'hg.gradle'
hg.clone('path/to/repo')
不知何故,也许是因为 OP 已经五年了,但是
的 none
ext.someMethod = { foo ->
methodBody
}
方法对我有用。相反,一个简单的函数定义似乎在我的 gradle 文件中完成了工作:
def retrieveEnvvar(String envvar_name) {
if ( System.getenv(envvar_name) == "" ) {
throw new InvalidUserDataException("\n\n\nPlease specify environment variable ${envvar_name}\n")
} else {
return System.getenv(envvar_name)
}
}
我在脚本的其他地方调用它时没有前缀,即 retrieveEnvvar("APP_PASSWORD")
现在是 2020 年,所以我正在使用 Gradle 6.1.1.
@ether_joe 上面@InvisibleArrow 投票最高的答案确实有效但是你必须在之前定义你调用的方法 你称之为 - 即在 build.gradle
文件的前面。
你可以看一个例子here。我在 Gradle 6.5 中使用了这种方法并且它有效。
使用 Kotlin DSL (build.gradle.kts) 您可以定义常规函数并使用它们。
在调用点之前还是之后定义函数都没有关系。
println(generateString())
fun generateString(): String {
return "Black Forest"
}
tasks.create("MyTask") {
println(generateString())
}
如果要从另一个脚本导入和使用函数,请参阅 this answer and this answer。
作为我项目的一部分,我需要从目录中读取文件并在构建脚本中执行所有这些操作。对于每个文件,操作都是相同的(读取一些 SQL 查询并执行)。我认为这是一项重复性任务,最好在方法中编写。由于我是 Gradle 的新手,所以我不知道它应该如何。请帮忙。
下面给出了一种方法:
ext.myMethod = { param1, param2 ->
// Method body here
}
请注意,这是为项目范围创建的,即。对项目全局可用,可以在构建脚本的任何地方使用 myMethod(p1, p2)
如下调用,相当于 project.myMethod(p1, p2)
该方法也可以在不同的范围内定义,例如在任务内:
task myTask {
ext.myMethod = { param1, param2 ->
// Method body here
}
doLast {
myMethod(p1, p2) // This will resolve 'myMethod' defined in task
}
}
您可以通过以下方式定义方法:
// Define an extra property
ext.srcDirName = 'src/java'
// Define a method
def getSrcDir(project) {
return project.file(srcDirName)
}
您可以在 gradle 文档中找到更多详细信息 Chapter 62. Organizing Build Logic
如果您在任何其他文件中定义了任何方法 *.gradle - ext.method() 使其可在项目范围内访问。例如这里是
versioning.gradle
// ext makes method callable project wide
ext.getVersionName = { ->
try {
def branchout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
standardOutput = branchout
}
def branch = branchout.toString().trim()
if (branch.equals("master")) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
return stdout.toString().trim()
} else {
return branch;
}
}
catch (ignored) {
return null;
}
}
build.gradle
task showVersion << {
// Use inherited method
println 'VersionName: ' + getVersionName()
}
没有 ext.method() 格式,该方法将仅在声明的 *.gradle 文件中可用。这与属性相同。
一个包含方法的根对象示例。
hg.gradle 文件:
ext.hg = [
cloneOrPull: { source, dest, branch ->
if (!dest.isDirectory())
hg.clone(source, dest, branch)
else
hg.pull(dest)
hg.update(dest, branch)
},
clone: { source, dest, branch ->
dest.mkdirs()
exec {
commandLine 'hg', 'clone', '--noupdate', source, dest.absolutePath
}
},
pull: { dest ->
exec {
workingDir dest.absolutePath
commandLine 'hg', 'pull'
}
},
]
build.gradle 文件
apply from: 'hg.gradle'
hg.clone('path/to/repo')
不知何故,也许是因为 OP 已经五年了,但是
的 noneext.someMethod = { foo ->
methodBody
}
方法对我有用。相反,一个简单的函数定义似乎在我的 gradle 文件中完成了工作:
def retrieveEnvvar(String envvar_name) {
if ( System.getenv(envvar_name) == "" ) {
throw new InvalidUserDataException("\n\n\nPlease specify environment variable ${envvar_name}\n")
} else {
return System.getenv(envvar_name)
}
}
我在脚本的其他地方调用它时没有前缀,即 retrieveEnvvar("APP_PASSWORD")
现在是 2020 年,所以我正在使用 Gradle 6.1.1.
@ether_joe 上面@InvisibleArrow 投票最高的答案确实有效但是你必须在之前定义你调用的方法 你称之为 - 即在 build.gradle
文件的前面。
你可以看一个例子here。我在 Gradle 6.5 中使用了这种方法并且它有效。
使用 Kotlin DSL (build.gradle.kts) 您可以定义常规函数并使用它们。
在调用点之前还是之后定义函数都没有关系。
println(generateString())
fun generateString(): String {
return "Black Forest"
}
tasks.create("MyTask") {
println(generateString())
}
如果要从另一个脚本导入和使用函数,请参阅 this answer and this answer。