Конвейер сценариев Jenkins: как применить аннотацию @NonCPS в этом конкретном случае c - PullRequest
2 голосов
/ 21 февраля 2020

Я работаю над сценарием Jenkins-Pipeline, которому нужно записать в файл строку с определенной кодировкой, как в следующем примере:

class Logger implements Closeable {

    private final PrintWriter writer

    [...]

    Logger() {
        FileWriter fw = new FileWriter(file, true)
        BufferedWriter bw = new BufferedWriter(fw)
        this.writer = new PrintWriter(bw)
    }

    def log(String msg) {
        try {
            writer.println(msg)
            [...]
        } catch (e) {
            [...]
        }
    }
}

Приведенный выше код не работает с PrintWriter это не сериализуемо, так что я знаю, что должен предотвратить преобразование некоторых кодов CPS. Однако я не знаю, как это сделать, поскольку, насколько я знаю, аннотация @NonCPS может применяться только к методам. Я знаю, что одним из решений было бы переместить весь код, связанный с выводом, в log(msg) и аннотировать метод, но таким образом мне пришлось бы создавать нового писателя при каждом вызове метода.

Есть ли у кого-то Идея о том, как я могу исправить свой код вместо этого?

Заранее спасибо!

1 Ответ

1 голос
/ 21 февраля 2020

Вот способ заставить эту работу использовать функцию log, определенную в общей библиотеке в vars\log.groovy:

import java.io.FileWriter
import java.io.BufferedWriter
import java.io.PrintWriter

// The annotated variable will become a private field of the script class. 
@groovy.transform.Field 
PrintWriter writer = null

void call( String msg ) {
    if( ! writer ) {
        def fw = new FileWriter(file, true)
        def bw = new BufferedWriter(fw)
        writer = new PrintWriter(bw)
    }

    try {
        writer.println(msg)
        [...]
    } catch (e) {
        [...]
    }     
}

В конце концов, создаются сценарии в папке vars как синглтон классы, которые идеально подходят для регистратора. Это работает даже без @NonCPS аннотации.

Использование в конвейере так же просто, как:

log 'some message'
...