How do I create a temporary file in Groovy? - groovy

In Java there exists the java.io.File.createTempFile function to create temporary files. In Groovy there doesn't seem to exist such a functionality, as this function is missing from the File class. (See: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html)
Is there a sane way to create a temporary file or file path in Groovy anyhow or do I need to create one myself (which is not easy to get right if I'm not mistaken)?
Thank you in advance!

File.createTempFile("temp",".tmp").with {
// Include the line below if you want the file to be automatically deleted when the
// JVM exits
// deleteOnExit()
write "Hello world"
println absolutePath
}
Simplified Version
Someone commented that they couldn't figure out how to access the created File, so here's a simpler (but functionally identical) version of the code above.
File file = File.createTempFile("temp",".tmp")
// Include the line below if you want the file to be automatically deleted when the
// JVM exits
// file.deleteOnExit()
file.write "Hello world"
println file.absolutePath

You can use java.io.File.createTempFile() in your Groovy code.
def temp = File.createTempFile('temp', '.txt')
temp.write('test')
println temp.absolutePath

The Groovy classes extend the Java file class so do it like you would normally do in Java.
File temp = File.createTempFile("temp",".scrap");
temp.write("Hello world")
println temp.getAbsolutePath()

Related

How to check if a file exists inside a directory in groovy?

I am trying to check if abcd.png exists inside the flows folder
flows/abcd.png
so in groovy I am doing this
def file = new File("flows/abcd.png").exists()
but it is returning false. When I do ls I can see the file exists inside the flows folder as well. What am I doing wrong? Any help would be appreciated
Also I tried with
"/flows/abcd.png"
".flows/abcd.png"
"./flows/abcd.png"
But it gives false for all the cases
you could use fileExists(), to check the existence of the file
if (fileExists("${workspace}/flows/abcd.png")) { do_something }

Append content from file using Email Ext Jenkins plugin

I have been modifying the default groovy template that the Email Ext plugin supplies.
Firstly, I had to modify the JUnitTestResult and need to format it accordingly to my need. I found in the it.JUnitTestResult, it is a reference to the ScriptContentBuildWrapper class. And then I was able to format the JUnitTestResult according to my need.
Now I am facing a second difficulty:
Along with those contents, I need to append more content from a file that resides in the job workspace. How to access the files that reside in the workspace directory.
I would be interested to know how I can access the build context object. Whats the java class name and things like that.
Just use build which returns an AbstractBuild
Try -
build.workspace
Which returns the FilePath of the directory where the build is being built.
See AbstractBuild.getWorkspace.
Tip: in Groovy, you can avoid the "get" and use field-like access notation.
Depending on which version of email-ext you are using, you can use the tokens provided to get access to things, so if you look at the token help, you'll see lots of tokens. These can be used in the groovy templates to do the same thing. For instance, the FILE token can be used in the Groovy by doing FILE(path: 'path/to/file') and it will replace with the contents of the file (only works on files that are below the workspace).
The build object is not available directly in all groovy scripts (e.g. groovy build script, groovy system build script, groovy post-build script, groovy script as evaluated in email-ext). The most portable way of obtaining build object in groovy script for a running build is:
import hudson.model.*
def build = Thread.currentThread().executable
Then you can get workspace and access files inside like this:
workspace = build.getEnvVars()["WORKSPACE"]
afilename = workspace + "/myfile"
afile = new File(afilename);
// afile.write "write new file"
// afile << "append to file"
// def lines = afile.readLines()

Groovy resource from classpath not loaded

Good day everyone.
I am using spock framework for testing in my groovy project(IDE - Intellij Idea 12.6). My spock specification class pass filename to groovy object for processing (that file is in classpath for sure), but when i try to get that file this way
def resource = getClass().getClassloader().getResourceAsStream(filepath)
assert resource != null : "No input stream found for path ${filepath}"
def rootNode = new XmlParser().parse(resource)
Then resource == null.
I tried debugging and in Expression Evaluation windows this code getClass().getResource(fileName) returns resource.
I tried to check which classloader used in first case (in class with the code) and in second case (Expression Evaluation window).
In first case classloader was sun.misc.Launcher$AppClassLoader#18dabf1, but in Expression Evaluation window classloader was groovy.lang.GroovyClassLoader$InnerLoader#1e69757 I suppose that's the reason my resource was null.
Can someone guide me about what I am doing wrong and how can I load that resource file ?
UPDATE:
Changed the way resource file was parsed. When filepath - full path to file this works, but if filepath is just file name and that file in classpath then resource == null
UPDATE2:
Change the way resource file loaded, clean up dependencies bit and all is working, I guess yesterday just wasn't my day.
The problem is very likely unrelated to Spock. It's hard to say from a distance what's causing it, but the safest way to read a resource is getClass().getClassLoader().getResourceAsStream() or Thread.currentThread().getContextClassLoader().getResourceAsStream(), depending on the environment.
Not sure what Groovy does when you do new File(resource), as there is no File(URL) constructor (only a File(URI) constructor). In any case, getting a File from a class path should be avoided whenever possible.
This is likely due to the fact that Groovy may interpret the class of the object differently that what you think is happening. See the following other StackOverflow item:
Why does groovy .class return a different value than .getClass()
When the class is wrong, then the ClassLoader may well by the bootstrap loader and getClassLoader returns null.
So instead of using a statement like
def resource = getClass().getClassloader().getResourceAsStream(filepath)
specify the actual class using a statement like
def resource = MyClass.class.getClassLoader().getResourceAsStream(filePath)
worked for me in nearly identical circumstances.
def resource = MyClass.class.getResourceAsStream(fileName)
or if you want the content of the file as String:
def str = new String(MyClass.class.getResourceAsStream(fileName).readAllBytes(), StandardCharsets.UTF_8)
Please note:
MyClass is used, not this.getClass();
In resources you must create the same directory structure as the package of your class, and put the files there;
fileName is just simply the name of the file, without any path;
You must clean and rebuild your project.

Debugging Groovy scripts running in a ScriptEngine from IDEA

In my app, I load a script file from the classpath into a String, then pass it into the ScriptEngine. Howerver, the breakpoint set in the script file doesn't trigger. How can I make it work? I use Intellij IDEA.
ScriptEngine engine = ...;
String script = FileUtils.readFileToString(file);
Bindings bindings = engine.createBindings();
Object result = engine.eval(script, bindings);
Since the ScriptEngine.eval() method only takes the script as a String or as a generic Reader, I don't think it is possible to achieve this. The GroovyScriptEngineImpl class will generate a script name and compile it to a class at runtime, which will make it hard (impossible?) for the debugger to know which breakpoint(s) are associated with the running script.
It might not be a solution for you, but if you instead invoke the script using GroovyShell, then it pretty much works out of the box.
Example:
File file = new File(scriptDir, "ScriptToRun.groovy");
Binding binding = new Binding();
Object result = new GroovyShell(binding).evaluate(file);
Just remember to set the correct package in the script if it is not located at the root.

get path to groovy source file at runtime

Given the following directory structure:
/home/some/random/foler/myScript.grooy
... how can I programmatically obtain the path to myScript.grooy parent directory right in the script itself?
Ultimately I'm trying to read in several files from the same directory the script is in.
EDIT: trying to run it on Windows 7, Groovy 2.0.1, groovy console
Well, the solution is in Java's File class:
println new File(".").absolutePath
If you want to obtain every groovy script in the same directory, maybe you could use some of other facilities in the Groovy JDK, like eachFile:
def files = []
new File(".").eachFile {
if (it.name.endsWith(".groovy") ) files << it
}
println files
If you want the running script name, well, you've got a problem (https://issues.apache.org/jira/browse/GROOVY-1642)
Accordingly to that JIRA, this is the current workaround (which doesn't always work):
URL scriptUrl = getClass().classLoader.resourceLoader
.loadGroovySource(getClass().name)

Resources