Gradle 的 CopySpec 过滤器方法签名与给出的示例有何关系?
Posted
技术标签:
【中文标题】Gradle 的 CopySpec 过滤器方法签名与给出的示例有何关系?【英文标题】:How does Gradle's CopySpec filter method signature relate to the example given? 【发布时间】:2020-02-18 09:18:39 【问题描述】:我正在尝试在我的 build.gradle 文件的 xml 文件中实现替换 $pattern
的东西:
processResources
eachFile FileCopyDetails fileCopyDetails ->
if (fileCopyDetails.name.contains("blueprint.xml"))
project.logger.quiet "Processing: " + fileCopyDetails.path
logger.quiet "" + project.ext.properties.entrySet()
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [prop1, value, prop2, value])
tokens:
似乎拿了一张地图。同样,这与函数签名有何关系?
将所有具有String值的属性转换为Map以输入到tokens:
def tokenMap = new LinkedHashMap()
def stringProps = project.ext.properties.entrySet().findAll entry -> entry.getValue() instanceof String
stringProps.each entry -> tokenMap.put(entry.key, entry.value)
查看 Gradle Javadoc 会发现一个过滤器函数,其签名似乎与示例不匹配。 据我所知,Map<String,?>
和 Class<? extends FilterReader>
与示例中的顺序不匹配。 有人可以将示例映射到函数签名以便我了解发生了什么吗?
CopySpec filter(Map<String,?> properties, Class<? extends FilterReader> filterType)
添加要在复制期间使用的内容过滤器。多次调用 过滤器,将其他过滤器添加到过滤器链中。每个过滤器应 实现 java.io.FilterReader。包括 org.apache.tools.ant.filters.* 用于访问所有标准 Ant 过滤器。
可以使用 groovy map 语法指定过滤器属性。
例子:
filter(HeadFilter, lines:25, skip:2) filter(ReplaceTokens, tokens:[copyright:'2009', version:'2.3.1'])
指定者:
filter
在接口ContentFilterable
中参数:
properties
- 过滤器属性映射filterType
- 要添加的过滤器类别返回: 这个
相关:
How is a token replaced in a file for a Gradle build product?
注意:
SimpleTemplateEngine 不起作用
processResources
filesMatching("**/features.xml")
// expand uses Groovy's SimpleTemplateEngine
project.logger.quiet "Processing: " + file
expand project.getProperties()
【问题讨论】:
【参考方案1】:这实际上是底层 Groovy 语法的一个特性。当方法的第一个参数声明为Map
时,Groovy 允许您按名称(即<name>: <value>
)指定方法参数。至关重要的是,命名参数可以出现在参数列表中的任何位置,即使在所谓的位置参数之后(即在方法签名中Map
之后声明的参数),它们将作为条目放入在初始 Map
参数中。有关详细信息,请参阅Groovy Language Documentation 中的混合命名参数和位置参数部分。
所以,Gradle filter
方法有签名
CopySpec filter(Map<String,?> properties, Class<? extends FilterReader> filterType)
第一个properties
参数是Map
类型,因此可以使用命名参数调用此方法。此外,还有一个位置参数,filterType
。因此,要调用此方法,您必须指定一个不带名称的参数,其类型为Class<? extends FilterReader>
,将用于filterType
,以及零个或多个命名参数,它们都将放入properties
映射中。
从文档中举一个例子:
filter(HeadFilter, lines:25, skip:2)
将意味着 filter
被调用
properties = [
lines: 25,
skip: 2
]
filterType = HeadFilter
以下任何调用都是等效的:
filter(lines:25, skip:2, HeadFilter)
filter(lines:25, HeadFilter, skip:2)
filter([lines:25, skip:2], HeadFilter)
此处的最后一次调用按位置传递两个参数(当第一个参数声明为 Map
时,您没有有使用命名参数)。
旁注
我很好奇为什么使用 expand
不起作用 - 应该!
【讨论】:
好的,expand() 的问题与 XML 无关。它与 expand()/SimpleTemplateEngine 的错误处理有关,如果在 XML 中找不到属性,则会失败。这是愚蠢的行为。我不确定如何正确吞下异常。甚至还有一张票:issues.apache.org/jira/browse/GROOVY-5093 这是因为我正在处理所有属性,无论它们是否存在于模板中。以上是关于Gradle 的 CopySpec 过滤器方法签名与给出的示例有何关系?的主要内容,如果未能解决你的问题,请参考以下文章
没有方法签名:com.crashlytics.tools.gradle.CrashlyticsPlugin On Mac [关闭]
安卓 自动签名 以及如何验证一个apk包是用你的签名文件签名的
Android:如何仅通过 Gradle 生成签名 APK? [复制]
Android - 签名的 APK - Gradle 执行失败