Trouble calling the fileTree( Object, Closure ) signature - groovy

I have a method that takes a string and a closure, which I include in my plugin convention:
def someMethod( String obj, Closure closure) {
println('HERE I AM')
confFileTree = project.fileTree( obj, closure )
}
From a Junit test I call it like so:
project.convention.plugins.license.licenseFiles( 'src') {
include "main/java/**"
include "main/resources/*.properties"
exclude "**/Licensed.java"
}
I know the method is called because 'HERE I AM' is printed. But I then get an error that says:
org.gradle.api.internal.MissingMethodException:
Could not find method fileTree() for arguments
[src, nl.javadude.gradle.plugins.license.tasks.LicenseTaskTest$_shouldScanFilesForLicenseWithExclude_closure1#3cbdb6ae]
on root project 'test'.
I should state that this code originally just called the Closure form of fileTree, with "from 'src'" in the closure, which works fine, but Gradle milestone 8 is telling me that it is a deprecated method.

Are you sure that the test is running against m8? In any case, here are a few suggestions for improvement (since I already know what you are trying to achieve):
I don't think you want to construct your own file tree. You just want the user to pass a 'filter' closure (like in your example) which you then apply to the source directory set (e.g. sourceSets.main.java) with the FileTree.matching(Closure) method. You'll get back a new file tree with the filter applied.
I recommend to use an extension rather than a convention object
You don't need the long-winded syntax when accessing convention objects or extensions from Groovy code. In your unit test example, you can just say project.licenseFiles(...) {...}.

Related

Is the `def` keyword optional? If so, why use it?

I am aware that a variable can be dynamically typed with the def keyword in Groovy. But I have also noticed that in some circumstances it can be left out, such as when defining method parameters, eg func(p1, p2) instead of func(def p1, def p2). The latter form is discouraged.
I have noticed that this is extendable to all code - anytime you want to define a variable and set its value, eg var = 2 the def keyword can be safely left out. It only appears to be required if not instantiating the variable on creation, ie. def var1 so that it can be instantiated as a NullObject.
Is this the only time def is useful? Can it be safely left out in all other declarations, for example, of classes and methods?
Short answer: you can't. There are some use cases where skipping the type declaration (or def keyword) works, but it is not a general rule. For instance, Groovy scripts allow you to use variables without specific type declaration, e.g.
x = 10
However, it works because groovy.lang.Script class implements getProperty and setProperty methods that get triggered when you access a missing property. In this case, such a variable is promoted to be a global binding, not a local variable. If you try to do the same on any other class that does not implement those methods, you will end up getting groovy.lang.MissingPropertyException.
Skipping types in a method declaration is supported, both in dynamically compiled and statically compiled Groovy. But is it useful? It depends. In most cases, it's much better to declare the type for a better readability and documentation purpose. I would not recommend doing it in the public API - the user of your API will see Object type, while you may expect some specific type. It shows that this may work if your intention is to receive any object, no matter what is its specific type. (E.g. a method like dump(obj) could work like that.)
And last but not least, there is a way to skip type declaration in any context. You can use a final keyword for that.
class Foo {
final id = 1
void bar(final name) {
final greet = "Hello, "
println greet + name + "!"
}
}
This way you can get a code that compiles with dynamic compilation, as well as with static compilation enabled. Of course, using final keyword prevents you from re-assigning the variable, but for the compiler, this is enough information to infer the proper type.
For more information, you can check a similar question that was asked on SO some time ago: Groovy: "def" keyword vs concrete type
in Groovy it plays an important role in Global and Local variable
if the variable name is same with and without def
def is considered local and without def its global
I have explained here in detail https://stackoverflow.com/a/45994227/2986279
So if someone use with and without it will make a difference and can change things.

Groovy - Type Check Closure Code Before Execution

I have a Groovy script that lets the user define some dynamic properties and methods and later executes a user-defined closure. A script would look like this:
// init properties and methods dynamically at runtime
context.prop1 = "Some test value"
context.method1 = { String input ->
"exec " + input.toUpperCase()
}
// "this" is set to the context variable from above
run {
println method1( prop1 )
}
So in the beginning of the script, a context is initialized with user-defined properties (e.g. prop1) and methods (e.g. method1). The context is then used as this pointer in the run closure. I have achieved this by dynamically extending the meta class of the context and setting the context as delegate of the run closure (with DELEGATE_FIRST as resolves strategy).
Currently I am struggling at type checking. Before executing the run closure, I would like to check if method1 really expects prop1. I have looked into the DelegatesTo annotation, but that doesn't seem to work for dynamically extended objects. I have also played with the AST, but since my knowledge on that topic is limited, I haven't come up with a solution. If what I want to achieve is possible, any pointers in the right direction would be greatly appreciated.
You want to add a method to a context at runtime and then type check this before execution of that method.
Type checking is done at compile time. That is before anything of your program is executed. There is normally no chance this can ever check anything that will only happen at runtime, unless you have a way to statically declare it and give the compiler the power to do the check. But this means normally, you will have to do static compilation.
One way would be to use type checking extensions, but I think in your case that might be overkill. A more simple way would be to use extension modules. And the most simple way would be to use custom script base class.
But for any of these solution you will need static compilation to really have type checking, same for DelegatesTo (which is more used in combination with extension modules). For a type checked DSL a mix of type checking extensions and extension modules can work very well. But you will of course loose more dynamic features of the language and some simplicity.

Groovy - Correct way to implement getProperty method

I need to run some code whenever a property value is retrieved, so naturally it made sense to define the getProperty method in my class. This method will get automatically called whenever a property value is retrieved. Here's roughly what I have in my class:
class MyClass
{
def getProperty(String name)
{
// Run some code ...
return this.#"${name}"
}
}
The problem with the above method occurs when someone tries to make the following call somewhere:
MyClass.class
This call ends up in the getProperty method looking for a property named "class", however, there is not actual property named "class" so we get a MissingFieldException.
What would be the correct way to implement running code whenever a property value is retrieved and deal with these kind of situtations.
Best is not to have a getProperty method if not needed. If you need one and you want to fall back on standard Groovy logic, then you can use return getMetaClass().getProperty(this, property), as can be found in GroovyObjectSupport. This will cover more than just fields.
This seems to be a common problem with this method. Map has the same issue. The developers of groovy got around the problem with Map by saying you need to use getClass() directly.

testing for empty groovy closure?

I want to let users supply a groovy class with a property that is a file-selector closure which I pass on to AntBuilder's 'copy' task:
class Foo {
def ANT = { fileset(dir:'/tmp/tmp1') }
}
in my code, I pick up the ANT property as 'fAnt' and pass to Ant:
ant.copy(todir:'/tmp/tmp2', fAnt)
This works - but, if the user passes in an empty closure (def ANT={}) or with a selector that doesn't select anything (maybe the fileset dir doesn't exist) then it blows up. I tried surrounding the ant copy with a try-catch to catch the InvokerInvocationException, but somehow the exception comes through anyway ... while I'm tracking that down, is there a way to read back a groovy Closure's contents as a string, or to test if it's empty?
In short: No. You can't decompile a closure in a meanngful way at runtime. If it's user supplied, the Closure could even be a Java class.
Long answer: If you want to do a lot of work, you might be able to, but it's probably not worth it. The Groovy parser is part of the API, so if you have access to the source, you can theoretically examine the AST and determine if the closure is empty. Look into the SourceUnit class.
It's almost certainly not worth the effort though. You're better off catching the exception and adding a helpful message like "You may have passed an empty closure or invalid fileset".
One mystery solved - the exception I need to catch is org.apache.tools.ant.BuildException - so I can just catch that to trap errors, but the original question remains - is there a way to examine a Closure's contents?

Groovy: meaning of 'this' inside a closure

The following example is adapted from 'Groovy in Action'
class Mother {
Closure birth() {
def closure = { caller ->
[this, caller]
}
return closure
}
}
Mother julia = new Mother()
closure = julia.birth()
context = closure.call(this)
println context[0].class.name // Will print the name of the Script class
assert context[1] instanceof Script
According to the book, the value of this inside the closure is the outermost scope (i.e. the scope in which julia is declared). Am I right in assuming that
this inside a closure evaluates to the scope in which the closure is called?
within the closure shown above, this and caller refer to the same scope?
Thanks,
Don
"this" in a block mean in Groovy always (be it a normal Java-like block or a Closure) the surrounding class (instance). "owner" is a property of the Closure and points to the embedding object, which is either a class (instance), and then then same as "this", or another Closure. I would forget about the scope thing totally for this part. So in the case above it is correct, that "this" refers to a mother.
And now to make things complicated... "this" and the implicit this are not the same in Groovy. So if you have a Closure {foo()} and {this.foo()} you can get differing results. this.foo() will always be resolved to the embedding class, while only foo() will be resolved using the Groovy meta object protocol (MOP) and can point to something entirely different. A builder may for example set a delegate on that Closure and catch the method invocation, for a Groovy builder that is standard. Anyway... that is why this part is called dynamic scoping.
Historic background:
Before Groovy 1.0 "this" was the Closure object itself. But was changed because actually calling this.foo() became impossible if a builder did capture all calls. then you had no way to call local methods from within the builder anymore. There was a lot of tries with changing the standard resolve strategy - and big emotional discussions too. But in the end, changing "this" to refer to the embedding class was a simple solution to the problem and is more in line with people coming from Java plus it let's you easily bypass the MOP if you insist.
Take a look at page 144
...this refers to the closure, not to
the declaring object. At this point,
closures play a trick for us. They
delegate all method calls to a
so-called delegate object, which by
default happends to be the declaring
object (that is, the owner). This make
the closure appear as if the enclosed
code runs in the birthday context.
For your questions;
this inside a closure evaluates to the scope in which the closure is called?
from the book they state that "this refer to the closure, not to the declaring object"
But from bertport and my experiment, it seems "this" is actually the declaring object.
Either ways, the answer is still "no" for your question.
within the closure shown above, this and caller refer to the same scope?
I'm afraid not.
Be aware that page 143 and 144 in Groovy in Action need some corrections
http://groovy.canoo.com/errata/erratum/show/5
http://groovy.canoo.com/errata/erratum/show/8
{
def self = ({ owner })()
}
owner: the enclosing object (this or a surrounding Closure).
Sake says, "this is the closure not the object where the closure [is] constructed." But when we run this script, we find that this is a Mother, not a Closure.

Resources