如何在build.gradle中定义和调用自定义方法

Tom*_*min 65 groovy gradle

作为我的项目的一部分,我需要从目录中读取文件并在构建脚本中执行所有这些操作.对于每个文件,操作是相同的(读取一些SQL查询并执行它).我认为这是一个重复的任务,更好地在一个方法内写.由于我是新手,我不知道应该如何.请帮忙.

Inv*_*row 88

一种方法如下:

ext.myMethod = { param1, param2 ->
    // Method body here
}
Run Code Online (Sandbox Code Playgroud)

请注意,这是为项目范围创建的,即.全局可用于项目,可以在构建脚本中的任何位置使用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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当我们使用`ext`时,范围被限制在定义的位置,即.如果它是在任务下定义的,则它是任务的本地.它的工作方式是通过实现[ExtensionAware]的实体(如项目,任务等)(http://www.gradle.org/docs/current/javadoc/org/gradle/api/plugins/ExtensionAware.html).这增加了一个[ExtraPropertiesExtension](http://www.gradle.org/docs/current/javadoc/org/gradle/api/plugins/ExtraPropertiesExtension.html),它通过`ext`指令配置. (3认同)

Row*_*ezi 26

如果您在任何其他文件中定义了任何方法*.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

的build.gradle

task showVersion << {
    // Use inherited method
    println 'VersionName: ' + getVersionName()
}
Run Code Online (Sandbox Code Playgroud)

如果没有ext.method()格式,该方法将仅在声明它的*.gradle文件中可用.这与属性相同.


Iva*_*nov 23

您可以通过以下方式定义方法:

// Define an extra property
ext.srcDirName = 'src/java'

// Define a method
def getSrcDir(project) {
    return project.file(srcDirName)
}
Run Code Online (Sandbox Code Playgroud)

您可以在gradle文档第62章"组织构建逻辑"中找到更多详细信息


Kev*_*lou 10

包含方法的根对象的示例.

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'
        }
    },

]
Run Code Online (Sandbox Code Playgroud)

build.gradle文件

apply from: 'hg.gradle'

hg.clone('path/to/repo')
Run Code Online (Sandbox Code Playgroud)


eth*_*joe 7

不知何故,也许是因为 OP 已经五年了,但没有一个

ext.someMethod = { foo ->
   methodBody
}
Run Code Online (Sandbox Code Playgroud)

方法对我有用。相反,一个简单的函数定义似乎在我的 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)
    }       
}
Run Code Online (Sandbox Code Playgroud)

我在我的脚本中的其他地方调用它,没有前缀,即 retrieveEnvvar("APP_PASSWORD")

这是 2020 年,所以我使用的是 Gradle 6.1.1。