A new, IDE friendly idiom for code reuse

50 views
Skip to first unread message

Edward Yang

unread,
Dec 2, 2017, 8:41:24 PM12/2/17
to job-dsl-plugin
Suppose you have:

job("foo") {
  parameters {
    stringParam("BAR", "default", "This is a chocolate bar")
  }
}

How can we abstract BAR out?


def bar(context) {
  context.with {
    stringParam("BAR", "default", "This is a chocolate bar")
  }
}

job("foo") {
  parameters {
    bar delegate
  }
}

This is OK, but if you load this in an IDE, 'stringParam' will have the "unresolved symbol" squiggly. Can we do better? Yes... with another helper function!

def parameters_snippet(@DelegatesTo(BuildParametersContext) c) {
  return { context -> context.with c }
}

def bar = parameters_snippet {
    stringParam("BAR", "default", "This is a chocolate bar")
}

job("a") {
    parameters { bar delegate }
}

Ah! Much better.

I am not completely satisfied though:

1. Is there a way to eliminate any mention of 'delegate' at the call site?! Based on reading through Groovy's docs, it doesn't look like it.
2. Is there an easy way to find out (e.g., inside the IDE) what context you are in? The context class names are not documented in https://jenkinsci.github.io/job-dsl-plugin/ so you end up having to guess and pray
3. Here's another way to skin this cat:


def parameters_snippet(@DelegatesTo(Job) c) {
  return { context -> context.with { parameters { c() } } }
}

def bar = parameters_snippet {
    stringParam("BAR", "default", "This is a chocolate bar")
}

job("a") {
    bar delegate
}

This sort of solves (2), since it means all you ever need to know is the name of the top-level context (Job), and then you can just write out the path for the configuration you want to set. But let's say I abstract both "bar" and "baz" this way; is it guaranteed that Groovy will always *append* these two parmeters to the parameters block? At least for 'parameters', this happens; but I am nervous that there might be some case where it doesn't; https://github.com/jenkinsci/job-dsl-plugin/wiki/User-Power-Moves#understanding-configxml-generation---multiple-calls-to-the-same-command claims that in some cases it may override. Am I guaranteed, for commands that take closures, for multiple invocations of the command to append?

Matt Sheehan

unread,
Dec 3, 2017, 4:10:37 PM12/3/17
to job-dsl...@googlegroups.com
Usually I do something similar to the first solution, but I grab the context class from the IDE and add it to the abstracted method signature.



--
You received this message because you are subscribed to the Google Groups "job-dsl-plugin" group.
To unsubscribe from this group and stop receiving emails from it, send an email to job-dsl-plugi...@googlegroups.com.
To post to this group, send email to job-dsl...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/job-dsl-plugin/c06a6999-4d79-4a31-bc6b-81c856e5cf7e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jakub Bocheński

unread,
Dec 12, 2017, 8:53:35 AM12/12/17
to job-dsl-plugin
> 1. Is there a way to eliminate any mention of 'delegate' at the call site?! Based on reading through Groovy's docs, it doesn't look like it.

I use a slightly different approach, calling closures with `with`

Closure bar = { .. }

job
("a") {
   
with bar
}

It allows me to do tricks like this one inside the Closures:
 if (delegate instanceof MavenJob) {
   preBuildSteps
( stuff )
 
} else {
   steps
(stuff)
 
}


Another example: https://github.com/jenkinsci/gitlab-plugin/issues/674#issuecomment-347852284
Reply all
Reply to author
Forward
0 new messages