0

Below pipeline codes works well:

pipeline {
    agent {
        label "test_agent"
    }

    stages {
        stage("test") {

            steps {
                script {
                    sh "echo 'number=${BUILD_NUMBER}' >log"

                    if (fileExists('log')) {
                        load 'log'
                        retVal = "${number}"

                    }
                    echo "${retVal}"
                }
            }
        }

    }
}

However, when I tried to put the logic of read file to a lib(named getNumber.groovy) and call it in pipeline, like this:

getNumber.groovy
def call() {
    def retVal
    if (fileExists('log')) {
        load 'log'
        retVal = "${number}"

    }
    return retVal
}

This is how the pipeline (test.groovy) call this lib:

@Library('lib') _
pipeline {
    agent {
        label "test_agent"
    }

    stages {
        stage("test") {

            steps {
                script {
                    sh "echo 'number=${BUILD_NUMBER}' >log"

                    def retVal = getNumber()

                    echo "${retVal}"
                }
            }
        }

    }
}

It always fail with below error:

        [Pipeline] End of Pipeline
    groovy.lang.MissingPropertyException: No such property: number for class: getNumber
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:458)
        at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:34)
        at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)

Any suggestion? How to fix it if I want to encapsulate the logic in a lib?

[Edit] If I change this segment

                    load 'log'
                    retVal = "${number}"

to this:

    def matcher = readFile('log') =~ '^number=(.+)'
    retVal=matcher ? matcher[0][1] : null

it works. But I just curious why the previous one can't work.

Phoenix
  • 95
  • 3
  • 10
  • Woudnt it be getNumber.call{} ? – Ravindranath Barathy Apr 27 '18 at 01:23
  • @Curious, no need, call getNumber could invoke the function because we could find it loaded the file successfully. However, it could not recognize property "number". – Phoenix Apr 27 '18 at 02:13
  • How did you configure the library in Jenkins? As a global library? Maybe try to specify it (at least for testing) directly in the `@Library` annotation (`@Library('http://github.com/my/library')`). – StephenKing Apr 27 '18 at 03:55
  • Actually.. what does the job output say? It should start with like `Loading library ...`. If this is missing, you haven't correctly configured the library. – StephenKing Apr 27 '18 at 03:56
  • @StephenKing I tried there code. The shared library setup and start correctly. This question is about how `load` step works, and why it works differently in shared library. – tianzhipeng Apr 27 '18 at 10:50
  • I didn't even notice the `load` step. This is for loading functions/libraries, not reading file contents. – StephenKing Apr 27 '18 at 12:13
  • I am sure the library defined and called correctly because it showed load step successfully. You could try this code. If you try the first segment of codes, it works. But if you put the logic in library and call it, the error is output as I posted. Definitely you could find the function is loaded (you could add some log info in the library part and you will find it is printed). I am really confused why the function can't work correctly when it is called as a library. – Phoenix Apr 27 '18 at 18:56
  • @StephenKing, it can be used to read properties, just like "Inject environment variables" in freeStyle jenkins job. Of course we can use "readFile" to get the content of files, but "load" function doesn't need to parse the file if the content organized as "=" – Phoenix Apr 30 '18 at 16:26
  • Ah, mixed it up with the `library` step. – StephenKing Apr 30 '18 at 17:27

0 Answers0