Как я могу изменить исходный код Java в своем проекте Gradle до компиляции без изменения файлов на диске? - PullRequest
3 голосов
/ 11 января 2020

У меня есть проект Gradle. В моем исходном коде у меня есть некоторые аннотации (среди прочего), которые принимают ту же строку. Тем не менее, эта же строка существует в файле конфигурации, и я хотел бы сослаться только на этот файл, поэтому мне нужно изменить эту строку только в одном месте, чтобы изменить все его экземпляры. Из-за этого мне пришлось бы читать строку из файла, то есть строка не является константой времени компиляции. Таким образом, я не могу использовать строку, считанную из файла, в качестве аргумента аннотации.

// I have this.
@Annotation("some_string")
Object a;

@Annotation("some_string")
Object b;


// This doesn't work
String ss = // read a file, fetch the string from the file.

@Annotation(ss)
Object a;

@Annotation(ss)
Object b;

Мне было интересно, есть ли способ в Gradle изменить исходный код до компиляции таким образом, который позволяет мне чтобы одна переменная управляла всеми аргументами аннотации.

Т.е. в исходном коде я мог бы иметь @Annotation("%%some_string%%") и заменить все вхождения %%some_string%% на переменную в задаче Gradle. Было бы достаточно легко просто изменить каждый исходный файл, например,

def annotation_variable = // read a file, fetch the string from the file.
for ( f in srcFileTree ) {
    def text = file(f).text
    file(f).text = text.replaceAll("%%some_string%%", annotation_variable)
}

Однако это навсегда изменило бы исходный файл. Итак, я ищу способ изменить файл в конвейере, фактически не изменяя файл на диске. Есть ли способ сделать это?

Ответы [ 2 ]

2 голосов
/ 11 января 2020

Поместите ваши java шаблоны в другой каталог, чем ваши обычные java источники (например, src/template/java). Это уменьшит «работу», требуемую Gradle, а также будет означать, что ваша IDE не будет пытаться скомпилировать шаблоны.

Затем добавьте задачу для замены токенов в ваших шаблонах и скопируйте их в каталог под $buildDir (чтобы они удалялись с помощью «clean» и никогда не передавались в git)

task generateJava(type: Copy) {
   from 'src/template/java'
   into "$buildDir/generated/java"
   filter(ReplaceTokens, tokens: [someToken: 'someReplacement'])
} 

Теперь добавьте сгенерированный каталог в «main» java sourceSet и подключите задачу к DAG

sourceSets.main.java.srcDir  "$buildDir/generated/java"
compileJava.dependsOn 'generateJava'

Если ваша IDE имеет интеграцию Gradle, ваша IDE также должна теперь скомпилируйте сгенерированные источники

См. «Фильтрация файлов по мере их копирования» в работе с файлами docs

0 голосов
/ 11 января 2020

Вы можете изменить выходной файл вместо исходного. Пример задания «Война» и фильтра replaceTokens (используйте любимое задание и фильтр):

tasks.withType(War) { warTask ->
        ...
        from('src/main/java/YOUR_PACKAGE') {
            include YOUR_FILE(s)

            filter ReplaceTokens, beginToken: '@', endToken: '@', tokens: [
                    'YOUR_TOKEN_NAME': YOUR_VALUE
            ]
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...