简体   繁体   中英

Using an enum loaded from another Groovy file (Jenkins Pipeline issue)

I have the following Groovy script as part of a Jenkins pipeline

permissions.groovy

enum PermissionType {
  ANONYMOUS,
  AUTHENTICATED
}

def get_job_permissions(PermissionType permission) {
  ...
}

return this

I load this file into another Groovy file as part of my Jenkins pipeline and call get_job_permissions passing through one of the enums as a parameter.

pipeline.groovy

def job_permissions = load 'permissions.groovy'
job_permissions.get_job_permissions(job_permissions.PermissionType.AUTHENTICATED)

Jenkins fails on this with the following error (I've verified that in this case 'Script3' is the call to get_job_permissions with the enum parameter).

groovy.lang.MissingPropertyException: No such property: PermissionType for class: Script3

I know the script load and call is correct, as I can change the signature of get_job_permissions to the following, pass through a random string in pipeline.groovy and the call goes through correctly.

def get_job_permissions(def permission) {
  ...
}

If I don't change the signature, and still pass through a random string, Jenkins fails the build as it can't find the method it thinks I'm calling (which is true, it's not there, it's expecting a PermissionType type).

I've tried a number of different things to expose PermissionType to the calling script

  • Adding @Field (not legal Groovy)
  • Changing the enum definition to public def PermissionType (not legal Groovy)
  • Removing and adding public to the enum definition
  • Changing the case (though I believe enums need to start with an upper case character?)

None of these solutions allow me to reference the enum type from the calling script, and I understand this is because I'm trying to access a type by referencing it through an instance of the script.

But if I can't do it this way, what is the best way to do it?

Thanks

I managed to get something to work - I certainly know it's probably not the right, or even good, way to do it, but it unblocked me and gave me what I needed.

Rather than define the enum in a script as you normally would

enum PermissionType {
  ANONYMOUS,
  AUTHENTICATED
}

I created a class containing the enum with member variables initialised to the values within the enum.

permissions.groovy

public class PermissionTypes {

  public enum Values {
    ANONYMOUS,
    AUTHENTICATED
  }

  public final PermissionTypes.Values ANONYMOUS = PermissionTypes.Values.ANONYMOUS
  public final PermissionTypes.Values AUTHENTICATED = PermissionTypes.Values.AUTHENTICATED
}
@Field final PermissionTypes Permissions = new PermissionTypes()

I can then expose an instance of that class in the script, load it as normal and I finally get access to the enum values.

pipeline.groovy

def job_permissions = load 'permissions.groovy'
job_permissions.get_job_permissions(job_permissions.Permissions.AUTHENTICATED)

I think we can all agree this is slightly bonkers, but it gave me what I needed.

Only issues I have with this (which I can live with for now)

  • You can only load the file ones in a script otherwise you get a duplicate class exception
  • You can't use the type in an external method, only the values - OK for me since any methods taking in the type are local to the class definition

Would still love to know the right way to do this :)

I ran into this problem recently and found a different solution that looks less hacky.

enum PermissionType {
  ANONYMOUS,
  AUTHENTICATED
}

def get_job_permissions(PermissionType permission) {
  ...
}

// Do this before you return out to make the enum available as well
this.PermissionType = PermissionType

return this

I prefer to use:

MyEnumClass.groovy:

package cl.mypackage.utils

class MyEnumClass {
    static enum MyEnum {
        FOO, BAR, QWERTY
    }
}

How to use:

import cl.mypackage.utils.MyEnumClass

def in_some_place() {
    def fooEnum = MyEnumClass.MyEnum.FOO
}

Regards

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM