Launch grails command from grails application - grails

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 :-(

Related

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.

Executing a gant script from a grails project

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()

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()
}

Grails: Automating Grails Plugin Installations

Imagine that we have a grails plugin (that we're developing) and also a test app that we're using to test the grails plugin. I'm trying to test the _Install.groovy script of the plugin, but it's quite a process each time.
Can anyone please recommend way using gant or bash to automate the process of:
Increment the version of the plugin
Package the plugin
Check if the plugin is already installed in the test app and if it is, remove it.
Re-install the plugin.
Much appreciated,
The answer for me was to create a groovy/GANT script and execute it via the command line.
In my plugin, I have a scripts directory and in there I created a script called Deploy.groovy.
Running the command
grails deploy
Automatically executes this script. The script packages the plugin using built in grails targets, then executes grails commands via the commandline.
plugin-home/scripts/Deploy.groovy
includeTargets << grailsScript("PackagePlugin_")
includeTool << gant.tools.Execute
target(main: "This is the script that tries to test what's going on...") {
println ("1. Package the plugin")
packagePlugin()
println ("2. Confirm the directory")
execute.shell("cd ~/quirk-projects/admin-cms-plugin-test && pwd")
println ("3. Remove the plugin ")
execute.shell("cd ~/quirk-projects/admin-cms-plugin-test && grails uninstall-plugin grails-admin-cms-plugin")
println ("4. Install the plugin ")
execute.shell("cd ~/quirk-projects/admin-cms-plugin-test && grails install-plugin ../admin-cms-plugin/grails-admin-cms-plugin-0.1.zip")
println ("5. Run Application")
execute.shell("cd ~/quirk-projects/admin-cms-plugin-test && grails run-app")
println ("6. Your plugin is ready for testing...")
}
setDefaultTarget(main)
To increment, I wrote a script that simply edits the source file and increments the version number:
plugin-home/scripts/_Events.groovy
eventCompileStart = { kind ->
println("Incrementing Version Number for next time")
def version = metadata.'version'
if (!version) {
version = '1'
} else {
version = version.toInteger() + 1
}
metadata.'version' = version.toString()
metadata.persist()
def file = new File("${basedir}/AdminCmsPluginGrailsPlugin.groovy")
def script = file.text
def array = script.split("\n")
for (int i = 0 ; i < array.length; i++) {
if (array[i].indexOf("def version") > -1) {
array[i] = " def version = 0." + version
}
}
def newScript = array.join(System.getProperty("line.separator"))
file.text = newScript
}

Resources