jenkinsgroovyenumsjenkins-shared-libraries

Jenkins/Groovy: How to declare/use an enum outside class?


I have a Jenkinsfile that calls function setup() from shared-lib my_lib:

// Jenkinsfile
@Library('my_lib@dev') my_lib

import groovy.json.JsonOutput

pipeline {
  agent any

  stages {
    stage( "1" ) {
      steps {
        script {
          d = my_lib.setup();
        }
      }
    }
  }
}

The shared-lib function tries to assign enums to dictionary elements.

// vars/my_lib.groovy
def setup() {
  def d = [:]
  d.a = org.foo.Foo.Event.A  // ok
  d.b = my_enum.getEvent()   // ok
  d.c = my_enum.Event.A      // groovy.lang.MissingPropertyException: No such property: Event for class: my_enum
}
// src/org/foo/Foo.groovy
public class Foo {
  enum Event {
    A,
    B;
  }
  def Foo() {}
}

my_enum.groovy declares an enum, and a getter-function that returns one of those enums:

// vars/my_enum.groovy
public enum Event {
  A,
  B;
  def Event() {}
}

def getEvent() { return Event.A }

Problem:
The above code fails in my_lib.groovy at d.c = my_enum.Event.A with error groovy.lang.MissingPropertyException: No such property: Event for class: my_enum

Questions:
Why does assigning my_enum.Event.A fail?
How do I define and use a "file-scoped" enum?
Why does assigning an enum scoped to my_enum fail when a class-scoped enum is okay, and also a simple wrapper function in my_enum that returns Event.A also okay?


Solution

  • 1/ Why does assigning my_enum.Event.A fail?

    here is a plain groovy code that approximately corresponds to my_enum.groovy from your question in jenkins/groovy

    class MY_ENUM {               // <- this class is not accessible for you in jenkins
      enum Event {A,B}
      def getEvent() { Event }    // <- i have changed this func on purpose 
    }
    def my_enum = new MY_ENUM()   // <- however my_enum variable is visible for you in jenkins
    
    println MY_ENUM.Event.A       // works in plain groovy, but MY_ENUM class is not accessible in jenkins
    

    to access inner enum in java/groovy you have to use CLASSNAME.ENUMNAME.KEY accessor - link

    but MY_ENUM is not accessible for you in jenkins to do this MY_ENUM.Event.A

    and when you are accessing my_enum.Event.A - you are trying to get Event from instance of the class instead of class itself - so, it fails

    2/ How do I define and use a "file-scoped" enum?

    with function getEvent() defined as in class above you could do this:

    my_enum.getEvent().A
    

    or this - groovy will find getEvent() function for this accessor

    my_enum.event.A
    

    not sure but try to define my_enum.groovy like this:

    enum Event {A,B}
    return Event
    

    then this should work:

    my_enum.A
    

    3/ Why does assigning an enum scoped to my_enum fail when a class-scoped enum is okay

    because each file in jenkins results an instance of class but class itself is not accessible.