Can config slurper parse methods with map as input variable - grails

I am trying to parse a groovy file using config slurper like this .
fileContents = '''deployment {
deployTo('dev') {
test = me
}
}'''
def config = new ConfigSlurper().parse(fileContents)
The above code works because the deployto('dev') is simply accepting a string. But I add an extra parameter to it , it fails with this exception:
fileContents = '''deployment {
deployTo('dev','qa') {
test = me
}
}'''
def config = new ConfigSlurper().parse(fileContents)
It fails with the following exception :
Caught: groovy.lang.MissingMethodException: No signature of method: groovy.util.ConfigSlurper$_parse_closure5.deployTo() is applicable for argument types: (java.lang.String, java.lang.String, script15047332444361539770645$_run_closure3$_closure10) values: [dev, postRun, script15047332444361539770645$_run_closure3$_closure10#6b8ca3c8]
Is there a way around reading this config file with extra args in a module?

You are almost there. In order to use list of values, please do the below change.
From:
deployTo('dev','qa')
To:
deployTo(['dev','qa'])
It would be:
def fileContents = '''deployment { deployTo(['dev','qa']) { test = me } }'''
def config = new ConfigSlurper().parse(fileContents)​

Related

Jenkinsfile syntax error: No such property

I'm trying to test a binary with latest commit id in Jenkins. Error happens at send slack message stage:
def kResPath = "/tmp/res.json" // global variable, where json file is dumped to; declared at the very beginning of Jenkinsfile
def check_result_and_notify(tier, result) {
def kExpected = 3
def kSuccessSlackColor = "#00CC00"
message = "Test ${tier} result: ${result}\n"
def test_result = readJSON file: kResPath
// 0 means index, "benchmarks", "real-time" is the key
real_time = test_result["benchmarks"][0]["real_time"]
if (real_time > kExpected) {
message += String.format("real time = %f, expected time = %f", real_time, kExpected)
}
slackSend(color: ${kSuccessSlackColor}, message: message.trim(), channel: "test-result")
}
The json file looks like:
{
"benchmarks": [
{
"real_time": 4,
},
{
"real_time": 5,
}
],
}
The error message I've received is hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: kResPath for class: WorkflowScript
Can someone tell me what's wrong with my code?
Is there any way I could test it locally so that I don't need to commit it every single time? I googled and find it needs server id and password, which I don't think accessible to me :(
Your kResPath variable is undefined in the scope of that function or method (unsure which based on context). You can pass it as an argument:
def check_result_and_notify(tier, result, kResPath) {
...
}
check_result_and_notify(myTier, myResult, kResPath)
and even specify a default if you want:
def check_result_and_notify(tier, result, kResPath = '/tmp/res.json')

jenkins job dsl - No signature of method: java.lang.String.call()

I am unable to run this piece of code:
buildPath = 'applications'
buildJob(['java', 'nodejs'])
def buildJob(def jobList){
for(job in jobList){
def jobName = "${job}_seed"
def jobDescription = "Jenkins DSL seed for ${job}"
def jobScriptPath = "resources/dsl/${jobName}.groovy"
job("${buildPath}/${jobName}")
}
}
So, I am getting this error:
Processing provided DSL script
ERROR: (script, line 12) No signature of method: java.lang.String.call() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl) values: [applications/java_seed]
Possible solutions: wait(), any(), wait(long), take(int), each(groovy.lang.Closure), any(groovy.lang.Closure)
Finished: FAILURE
I do not see where or what is causing this error. I created a single job outside of the buildJob(def jobList) function and it is working but I need to do the loop to automation the jobs creation.
Any ideas?
Posting a similar issue i have run into. Isn't much around the web on this issue.
No signature of method: java.lang.String.call() is applicable for argument types: (java.lang.String) values: [some-value]
Say we are implementing a job dsl plugin (https://github.com/jenkinsci/multibranch-build-strategy-extension-plugin) like:
includeRegionBranchBuildStrategy {
includedRegions(String value)
}
And we have code like:
def includedRegions = r ? String.join("\n", r) : null
branchSources {
branchSource {
buildStrategies {
if(includedRegions){
includeRegionBranchBuildStrategy {
includedRegions(includedRegions)
}
}
}
}
}
Need to rename your variable to get it to work! e.g the method can't have the same name as a var defined above.
def regions = r ? String.join("\n", r) : null
branchSources {
branchSource {
buildStrategies {
if(regions){
includeRegionBranchBuildStrategy {
includedRegions(regions)
}
}
}
}
}
you are iterating string array in the following line:
for(job in jobList){
and using variable job for this.
then you try to invoke method call on this variable:
job("${buildPath}/${jobName}")

Grails External Configuration. Can't access to external variable. Getting always [:]

I can't have my 'folder' external variable working. Always I'm getting [:].
I'm developing on Grails under Windows (this is why the external configuration file looks like file:C:\path\to/file).
I'm using external configuration in another project without problems, in the same way that I'm showing below.
I have this:
Config.groovy:
environments {
development {
grails.config.locations = [ "file:${userHome}/.grails/${appName}-config.groovy" ]
}
}
myApp-config.groovy:
stats.feed.wsdl.folder = '/static'
Controller and Service:
class WsdlController {
def wsdlService
def index = {
wsdlService.getEventsSchedule()
}
}
class WsdlService {
def grailsApplication
def getEventsSchedule = {
println "Locations: ${grailsApplication.config.grails.config.locations}"
println "Folder: ${grailsApplication.config.stats.feed.wsdl.folder}"
}
}
Console:
Locations: [file:C:\Users\myUser/.grails/myApp-config.groovy]
Folder: [:]
Any clue?
Thanks!
Updated!
This is the whole myApp-config.groovy:
println 'Start'
stats.feed.wsdl.folder = "/stats"
println 1
stats.feed.wsdl.folder.events = "${stats.feed.wsdl.folder}/events"
println 2
stats.feed.wsdl.folder.teams = "${stats.feed.wsdl.folder}/teams"
println 'End'
This is not working, the console shows:
Start
1
But if I change the variable names, it works.
println 'Start'
stats.feed.wsdl.folder = "${playcall.static.resources.folder}/stats"
println 1
stats.feed.wsdl.events.folder = "${stats.feed.wsdl.folder}/events"
println 2
stats.feed.wsdl.teams.folder = "${stats.feed.wsdl.folder}/teams"
println 'End'
Console:
Start
1
2
End
You create a property and declared this as a string:
stats.feed.wsdl.folder = "/stats"
In that way you isnt't able to add subproperties. So, to keep something close to what you want, you can do this:
stats.feed.wsdl.folder.base = "/stats"
stats.feed.wsdl.folder.events = "${stats.feed.wsdl.folder.base}/events"
stats.feed.wsdl.folder.teams = "${stats.feed.wsdl.folder.base}/teams"

commonsMultipartFile trouble

Hi I have am trying to implement a file upload in my application where the file uploaded is parsed and an entry is created in the database using that information.
def save = {
def file = request.getFile("file");
def filename = file.getOriginalFilename();
def type = filename.split('\\.');
if(!file.isEmpty()){
if(type[1] == "properties"){
redirect(action:"parsePropertyFile", params:params);
}
}
}
def parsePropertyFile = {
println "\n"
println params.file;
println "\n";
def f = params.file;
println f;
def filename = f.getOriginalFilename();
println filename;
}
when I print out f this is output:
org.springframework.web.multipart.commons.CommonsMultipartFile#29d32df9
but when I try to call getOriginalFilename() on f I get the following error:
groovy.lang.MissingMethodException: No signature of method:
java.lang.String.getOriginalFilename() is applicable for argument types: () values: []
I also printed out file from the save function and the output of that is also:
org.springframework.web.multipart.commons.CommonsMultipartFile#29d32df9
so why am I getting the error?
Instead of redirecting, can you just call your another function? Redirect will issue an http redirect with the file as param with no need.
if(type[1] == "properties") {
parsePropertyFile(file)
}
And then:
private def parsePropertyFile(def file) {
String filename = file.getOriginalFilename();
...
}
In your parsePropertyFile action you aren't getting a File object, you're getting the String from params. Just like in your save action, you need to do
def f = request.getFile('file')
println f.getOriginalFilename()

convert CommonsMultipartFile to file

I am using a plugin that uploads files as a CommonsMultipartFile. The upload works fine, but I am trying to use another plugin to read the files header (the mp3 header) but it will not take CommonsMultipartFile, only regular files. Is there a way to either convert the CommonsMultipartFile to a file or have some other work around. I've tried copying the file from where it gets uploaded from, but it doesn't seem to work. here is what i have so far:
if (request instanceof MultipartHttpServletRequest) {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
CommonsMultipartFile file = (CommonsMultipartFile)multiRequest.getFile("files");
moveFile(file)
}
private moveFile(CommonsMultipartFile file){
def userId = getUserId()
def userGuid = SecUser.get(userId.id).uid
def webRootDir = servletContext.getRealPath("/")
def userDir = new File(webRootDir, "/myUsers/${userGuid}/music")
userDir.mkdirs()
file.transferTo( new File( userDir,file.originalFilename))
def myFile = new File( "/myUsers/${userGuid}/music/" + file.originalFilename)
AudioFile audioFile = AudioFileIO.read(file);
//AudioFile is expecting a file, not a CommonsMultipartFile
}
When i do this, though, i get this error:
groovy.lang.MissingMethodException: No signature of method: static org.jaudiotagger.audio.AudioFileIO.read() is applicable for argument types: (org.springframework.web.multipart.commons.CommonsMultipartFile) values: [org.springframework.web.multipart.commons.CommonsMultipartFile#10a531]
Thanks
jason
Your code copied MultiPart file to a File, but still used Multipart file for AudioFileIO.
It must be like:
private moveFile(CommonsMultipartFile file){
def userId = getUserId()
def userGuid = SecUser.get(userId.id).uid
def webRootDir = servletContext.getRealPath("/")
def userDir = new File(webRootDir, "/myUsers/${userGuid}/music")
userDir.mkdirs()
File myFile = new File( userDir,file.originalFilename)
file.transferTo(myFile)
//
// !!!!!! you have to pass myFile there
//
AudioFile audioFile = AudioFileIO.read(myFile)
}

Resources