Executing a gant script from a grails project - grails

I have written my own gant script which works fine from the command line. Now I need to run this script from a grails project like this:
def outputMessage
try{
GroovyScriptEngine engine = new GroovyScriptEngine("/www", this.getClass().getClassLoader());
engine.run("scripts/MyOwnScript_.groovy", "param1 param2")
outputMessage = "<br> OK: Script run successfully"
}
catch (Exception e) {
outputMessage += "<br> ERROR: There has been running the script"
}
The error I am getting is "No such property: includeTargets for class: MyOwnScript_", as my gant script requires some other scripts.
Does anybody know a proper way to get it working?

Have you tried to get path to your script folder and execute an external process like
["groovy", "scripts/MyOwnScript_.groovy", "param1", "param2"].execute()
See here for more info about running external process in groovy

Answering my own question. The main problem was that I need to run the grails using the full path like this:
Map<String, String> env = System.getenv()
final processBuilder = new ProcessBuilder()
processBuilder.directory(new File("folderFromWhereIWantToRunTheGantScript"))
processBuilder.command([env['GRAILS_HOME']+"/bin/grails","MyOwnScript param1 param2"])
println processBuilder.directory()
Process proc = processBuilder.start()
proc.consumeProcessOutput(out, err)
proc.waitFor()

Related

Jenkins pipeline script to copy or move file to another destination

I am preparing a Jenkins pipeline script in Groovy language. I would like to move all files and folders to another location. As Groovy supports Java so I used below java code to perform the operation.
pipeline{
agent any
stages{
stage('Organise Files'){
steps{
script{
File sourceFolder = new File("C:\\My-Source");
File destinationFolder = new File("C:\\My-Destination");
File[] listOfFiles = sourceFolder.listFiles();
echo "Files Total: " + listOfFiles.length;
for (File file : listOfFiles) {
if (file.isFile()) {
echo file.getName()
Files.copy(Paths.get(file.path), Paths.get("C:\\My-Destination"));
}
}
}
}
}
}
}
This code throws the bellow exception:
groovy.lang.MissingPropertyException: No such property: Files for
class: WorkflowScript
I tried with below code too, but it's not working either.
FileUtils.copyFile(file.path, "C:\\My-Destination");
Finally, I did try with java I/O Stream to perform the operation and the code is bellow:
def srcStream = new File("C:\\My-Source\\**\\*").newDataInputStream()
def dstStream = new File("C:\\My-Destination").newDataOutputStream()
dstStream << srcStream
srcStream.close()
dstStream.close()
But it's not working either and throws the below exception:
java.io.FileNotFoundException: C:\My-Source (Access is denied)
Can anyone suggest me how to solve the problem and please also let me know how can I delete the files from the source location after copy or move it? One more thing, during the copy can I filter some folder and files using wildcard? Please also let me know that.
Don't execute these I/O functions using plain Java/Groovy. Even if you get this running, this will always be executed on the master and not the build agents. Use pipeline steps also for this, for example:
bat("xcopy C:\\My-Source C:\\My-Destination /O /X /E /H /K")
or using the File Operations Plugin
fileOperations([fileCopyOperation(
excludes: '',
flattenFiles: false,
includes: 'C:\\My-Source\\**',
targetLocation: "C:\\My-Destination"
)]).
I assume I didn't hit the very right syntax for Windows paths here in my examples, but I hope you get the point.

groovy .execute waitFor hangs in Jenkins, but not CL

Good Day,
I have a groovy script running on a jenkins job like so.
//checkoutObjects
def command =""
for (i = 0; i <numOfObj; i++) {
command = "svn export -r "+DeploySetArray[i][1]+" "+DeploySetArray[i][0]+" D:/Jenkins/workspace/mmb.database.deploy"
//println command.execute().text
def proc = command.execute()
proc.waitFor()
println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}"
}
The above snippet works great, checks out all my SVN objects. Now the below part is where I have the issue.
command = "sqlplus mastermind/***#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=***)(PORT=1521))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=***))) #D:/BuildScripts/MMB/gather_invalids.sql"
def proc = command.execute()
println "This line is printed"
proc.waitFor()
println "This line is not printed"
println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}"
For some reason when trying to run this groovy script through Jenkins, or running directly from groovy console It waits on this line. However if i extract the sqlplus command exactly and run that by itself on CL it returns within a few seconds. I've looked up a few answers that I thought were close, but it seems weird that it works fine on command line but not through groovy. Any advice or pointers would be appreciated.
Thank you!
EDIT: I've tried using another command line tool "sql" instead of "sqlplus". Script is still hanging in the same spot, making me think its something to do with groovy
Found a solution, my issue wasn't groovy related though. The problem was with the commandline tools 'sql', and 'sqlplus'. When these programs are called with a script to execute, they will run the script and then without exiting prompt for more interaction. This caused the script to hang while it was waiting for more input. I got around this by preceeding my command with "exit | sqlplus..."
This link is what helped me.
https://serverfault.com/questions/87035/run-oracle-sql-script-and-exit-from-sqlplus-exe-via-command-prompt

Add command to Grails build process

I am using the grails-cdn-asset-pipline plugin. I've gone through the installation and configuration steps on GitHub and I reach the usage section which says
Add this command to your build process (usually before war generation and deployment).
// If all the settings are defined in your Config.groovy
grails asset-cdn-push
// Or
grails asset-cdn-push --provider=S3 --directory=my-bucket --gzip=true --storage-path=some-prefix --expires=365 --region=eu-west-1 --access-key=$MY_S3_ACCESS_KEY --secret-key=$MY_S3_SECRET_KEY
Where in my project do I put this command?
Is it something that I can do within the context of my project, or do I need to keep it separate in another build process and run it in an environment like Jenkins?
In _Events.groovy, I tried to invoke the script in the eventCreateWarStart, but I am having no luck there. (Code taken from this question)
eventCreateWarStart = { warName, stagingDir ->
def pluginManager = PluginManagerHolder.pluginManager
def plugin = pluginManager.getGrailsPlugin("cdn-asset-pipline")
def pluginDir = plugin.descriptor.file.parentFile
Map<String, String> env = System.getenv()
final processBuilder = new ProcessBuilder()
processBuilder.directory(new File("${cdnAssetPipelinePluginDir}/scripts"))
processBuilder.command([env['GRAILS_HOME']+"/bin/grails","cdn-asset-push"])
println processBuilder.directory()
Process proc = processBuilder.start()
proc.consumeProcessOutput(out, err)
proc.waitFor()
}
This link explains the run-script functionality which was merged into Grails 1.3.6. But I ran into the same problem of not knowing where to run it automatically.

Launch grails command from grails application

I am trying to run a grails command like "grails help" from a Grails application but all the tries I have done end up with "Error: Could not find or load main class org.codehaus.groovy.grails.cli.support.GrailsStarter".
Basically, I have tried
def p1 = "grails help".execute()
p1.waitFor()
println "return code: ${ p1.exitValue()}"
println "stderr: ${p1.err.text}"
println "stdout: ${p1.in.text}"
Also:
Runtime runtime = Runtime.getRuntime()
Process process = runtime.exec("grails help")
process.waitFor()
println "return code: ${ process.exitValue()}"
println "stderr: ${process.err.text}"
println "stdout: ${process.in.text}"
And finally:
def sout = new StringBuffer()
def serr = new StringBuffer()
final processBuilder = new ProcessBuilder()
processBuilder.directory(new File("/myFolder"))
processBuilder.command(["grails","help"])
println processBuilder.directory()
Process proc = processBuilder.start()
proc.consumeProcessOutput(sout, serr)
def status = proc.waitFor()
println 'sout: ' + sout
println 'serr: ' + serr
Of course, the "grails help" command is not the one I want to execute but fixing this one it will fix the one I need to run.
Any other ideas?
If I create a new app with grails 2.3.5 (grails create-app script-test), then declare a controller (grails create-controller test.Run) and change it so it looks like:
package test
class RunController {
def index() {
def t = [ 'grails', 'help' ].execute().text
render "<pre>$t</pre>"
}
}
Then run it with grails run-app, and go to localhost:8080/script-test/run, I get the grails help screen rendered as text to the web-page.
The problem you are going to have is that this won't work in production as you are probably going to deploy a war file, so grails won't be aware of where you are, or what you are doing (if indeed grails is installed on the server)
I think you need to re-think your strategy, whatever it is you are trying to do :-(

How to write connection script between Grails and Hadoop?

I need to copy the files which are generated within Grails to Hadoop dynamically. How will I write code for this in Grails? Whenever a file is generated it should be copied into Hadoop. If the incoming file already exists, it should get updated in Hadoop.
I used shell script to connect grails and hadoop.
I had all the commands to run hadoop jobs in myjob.sh (Workflow Script)
And i added the code to execute shell script in my controller
def scriptCom="/folderlocation/shellscript.sh"
println "[[Running $scriptCom]]"
def proc = scriptCom.execute()
def oneMinute = 60000
proc.waitForOrKill(oneMinute)
if(proc.exitValue()!=0){
println "[[return code: ${proc.exitValue()}]]"
println "[[stderr: ${proc.err.text}]]"
return null
}else{
println "[[stdout:$revisionid]]"
return proc.in.text.readLines()
}

Resources