Как сигнатура метода фильтра CopySpec от Gradle связана с приведенным примером? - PullRequest
2 голосов
/ 22 октября 2019

Я пытаюсь реализовать что-то, что заменит ${pattern} в XML-файлах в моем файле build.gradle:

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 в карту для ввода в 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 - Класс фильтра для добавления

Возвращает : это


Связано:

Каков токензаменены в файле для продукта сборки Gradle?


Примечание:

Что не работает, так это SimpleTemplateEngine

processResources {
    filesMatching("**/features.xml") {
        // expand uses Groovy's SimpleTemplateEngine
        project.logger.quiet "Processing: " + file
        expand project.getProperties()
    }

1 Ответ

2 голосов
/ 22 октября 2019

Это на самом деле особенность базового синтаксиса Groovy. Groovy позволяет указывать параметры метода по имени (то есть <name>: <value>) всякий раз, когда первый параметр метода объявляется как Map. Важно отметить, что именованные параметры могут появляться в любой точке в списке argumemt, даже после так называемых позиционных параметров (то есть тех, которые объявлены после Map в сигнатуре метода), и они будут помещены в виде записей вначальный Map параметр. Подробнее см. Раздел Сочетание именованных и позиционных параметров в документации на языке Groovy .

Итак, метод 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 не работает - оно должно!

...