String list/map properties: best way to handle for freestyle+pipeline

27 views
Skip to first unread message

Tim Van Holder

unread,
Sep 27, 2020, 9:29:59 AM9/27/20
to jenkin...@googlegroups.com
In my plugin (dotnet-sdk), I have several properties that are essentially lists or maps of strings; for example:
- list of targets to build
- properties (keyword/value) to pass to the build
- additional command-line options to pass

Currently, these are all string properties.
The logically-map properties are editable as a multiline text box and parsed as Java properties.
The logically-list properties are regular textboxes, with values processed at runtime via Util.tokenize().

This matches what the Ant plugin does, I believe, and it works well enough.
The only minor thing is that it's not obvious to have to use Java properties syntax for MSBuild properties.

However, for use in pipelines, this is not a very nice interface. I'd want to be able to use actual lists (or a map, in the case of the properties) to set the values.

Is there a way to do this properly? You can't seem to set any property that has no @DataboundSetter, and you can have only setter marked that way (which makes sense).
I suppose what I could do is:
- use an array/map for the backing field
- change the existing properties to "targetsString", "propertiesString" and "optionsString"
  - the setter maps the value into the backing field
  - the getter turns it back into a string (but there doesn't seem to be an inverse of Util.tokenize(), so making sure quoting is added where needed might be tricky)
- add new "targets" and "options" properties taking String..., and a "properties" taking a Map<String,String>
  - are getters required for this? or are setters enough for pipeline use

At that point, things would work, but the snippet generator would not offer any way to generate the nicer versions of the property.
I seem to recall there was an API to hook into to affect this, but I'm not sure.

The other path would be to try and get the jelly set up to have actual separate controls for each list entry (or a pair of controls for the map), with associated add/remove/move up/move down/... controls. That seems tricky at best.

I'd be happy to hear suggestions as to how to get this right and/or links to plugins that have already done this in a nice way.

Small secondary question: is there a page generated somewhere with all names used by builders/wrappers/... defined by (jenkinsci-managed) plugins? Just as a means of avoiding duplicates.

Jesse Glick

unread,
Sep 28, 2020, 1:45:04 PM9/28/20
to Jenkins Dev
On Sun, Sep 27, 2020 at 9:29 AM Tim Van Holder <tim.va...@gmail.com> wrote:
> Is there a way to do this properly?

Not really, no. See JENKINS-27901. You can define a nested
`Describable` for each entry, with one or two fields (value or key +
value), though the GUI may be clunky, and the Groovy syntax will be
verbose. You can use `CustomDescribableModel` to do custom mapping in
both directions, but this is pretty tricky and will not work well in
all contexts.

Tim Van Holder

unread,
Oct 14, 2020, 4:11:30 PM10/14/20
to jenkin...@googlegroups.com
Actually, it seems to work fairly well.
I just have
a) a String as the backing field. This allows for variable substitution from the freestyle side of things.
b) have the main getFoo()/setFoo() return/take a String[] or Map<String,String>, as applicable; these convert to/from String
c) have getFooString() and setFooString() operating on the field directly; these are marked as deprecated
d) the jelly uses fooString (and help-fooString.html etc)

The only issue I have is that the snippet generator is not inheritance-aware.
It will not normally generate anything for fooString because it is deprecated.
However if foo and fooString are inherited, BOTH are shown, despite fooString being deprecated.
I will likely be able to work around it by adding an override that just calls the super method, but I'll also look at submitting a PR, because this behaviour seems inconsistent.

Of course, JENKINS-27901 would be great to get the freestyle configuration more friendly.


--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CANfRfr0pJ2kE3sUs_B4qt%2BhN59dK6%3D0jL3QpAS09WM86rNkQmA%40mail.gmail.com.

Jesse Glick

unread,
Oct 14, 2020, 6:02:35 PM10/14/20
to Jenkins Dev
On Wed, Oct 14, 2020 at 4:11 PM Tim Van Holder <tim.va...@gmail.com> wrote:
> The only issue I have is that the snippet generator is not inheritance-aware.

I believe it is behaving as designed. Again, you can use
`CustomDescribableModel` to provide nondefault behavior.
Reply all
Reply to author
Forward
0 new messages