I am interested in using nomad to initialize a mysql database on a windows server that is without docker. I tried to create a job using the "exec" driver, "mysql" command, and an args argument with the host, username, password, etc.
job "gavin-setup" {
datacenters = ["dc1"]
group "gavin-setup-group" {
task "setup" {
driver = "exec"
config = {
command = "mysql"
args = [
"-hlocalhost",
"-ugavin",
"-pgavin_secret",
"gavin_database",
"<",
"C:\\gavin\\config\\create.sql"
]
}
}
}
}
The arguments aren't being passed along. I also tried removing the args and just using the command which did not work:
mysql -hlocalhost -ugavin -pgavin_secret gavin_database < C:\\gavin\\config\\create.sql
Is it possible to do this kind of database initialization setup on a first-time run of the application? Should nomad be capable of doing this? If not - should I be using some other process to do this kind of setup?
I ended up using the full path to the mysql.exe and discovered that nomad logs -stderr <assoc-id> was really helpful.
job "gavin-setup" {
datacenters = ["dc1"]
group "gavin-setup-group" {
task "create_db" {
driver = "exec"
config = {
command = "C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin/mysql.exe"
args = [
"-uroot",
"-pgavin_secret",
"-e",
"create database if not exists gavin_db;"
]
}
}
}
}
Is there any way to make gradle exec work like a shell exec? ie - understand executable files in the path?
We have code that needs to work on windows and unix - and many many scripts that are obviously different on both machines. While I can do a hack like this:
npmCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : '/usr/local/bin/npm'
and then run that command - the paths for some scripts are not necessarily set in stone - and it's just horrible code.
Is there any way to fix the problem - ie extend the exec task to find executable files in the path and run them?
How about something like:
if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows'))
{
commandLine 'cmd', '/c', 'commandGoesHere'
}
else
{
commandLine 'sh', '-c', 'commandGoesHere'
}
I'd love a better way - but I made a simple function that I put in our common that you use like this:
exec {
commandLine command("npm"), "install"
}
the function looks like this:
//
// find a command with this name in the path
//
String command( String name )
{
def onWindows = (System.env.PATH==null);
def pathBits = onWindows ? System.env.Path.split(";") : System.env.PATH.split(":");
def isMatch = onWindows ? {path ->
for (String extension : System.env.PATHEXT.split(";"))
{
File theFile = new File( path, name + extension);
if (theFile.exists())
return theFile;
}
return null;
} : {path -> def file = new File(path,name);if (file.exists() && file.canExecute()) return file;return null;}
def foundLocal = isMatch(file("."));
if (foundLocal)
return foundLocal;
for (String pathBit : pathBits)
{
def found = isMatch(pathBit);
if (found)
return found;
}
throw new RuntimeException("Failed to find " + name + " in the path")
}
I am using Gradle-2.11 and I am unable to find a way to create log files that logs debug level information. I don't want to do it through command line by redirecting the logs to the log file. I want Gradle code just like Apache Ant's 'record' task so that I can put that code in my build.gradle file wherever I want to create logs.
For ex: If I want to convert this ant task to gradle, then what would be the code:
<record name="${BuildLogPath}/${BuildLogFile}" append="no" loglevel="verbose" action="start"/>
Gradle integrates really nicely with Ant (https://docs.gradle.org/2.11/userguide/ant.html)
It doesn't automatically record each step. I didn't realize that is what you were asking. The updated below will produce the output and you can manually log.
ant.record(name: "${BuildLogPath}/${BuildLogFile}", append:false, loglevel: "verbose", action: "start")
ant.echo("start logging")
//... do stuff here
ant.echo(message: "end logging")
ant.record(name: "${BuildLogPath}/${BuildLogFile}", append:false, loglevel: "verbose", action: "stop")
This may do more of what you are asking. Note: This is something I adapted slightly from this excellent example:
http://themrsion.blogspot.com/2013/10/gradle-logging-writing-to-log-to-file.html
import org.gradle.logging.internal.*
String currentDate = new Date().format('yyyy-MMM-dd_HH-mm-ss-S')
String loggingDirectory = "${rootDir}/build/logs"
mkdir("${loggingDirectory}")
File gradleBuildLog = new File("${loggingDirectory}/${currentDate}_gradleBuild.log")
gradle.services.get(LoggingOutputInternal).addStandardOutputListener (new StandardOutputListener () {
void onOutput(CharSequence output) {
gradleBuildLog << output
}
})
gradle.services.get(LoggingOutputInternal).addStandardErrorListener (new StandardOutputListener () {
void onOutput(CharSequence output) {
gradleBuildLog << output
}
})
I'm used to working with Makefiles but my current project uses .qbs files. How do I run a simple terminal command through qbs without creating or requiring files? Similar to a phony rule in make.
The following works and shows "awesome" in my terminal.
import qbs 1.0
Project {
name: "cli"
Product {
name: "helloworld"
type: "application"
files: "TEST.c"
Depends { name: "cpp" }
}
Product {
type: ["custom-image"]
Depends { name: "helloworld" }
Rule {
inputsFromDependencies: ["application"]
Artifact {
fileTags: ["custom-image"]
}
prepare: {
var cmd = new Command("echo", "awesome")
return cmd
}
}
}
}
However I have to touch my dummy TEST.c file before each run. Without the helloworld dependency the Rule does not run.
Any ideas? Thank you very much!
It's buried in the documentation in a very non obvious place and further obscured by Command (which is not the correct way, lol). I've had your problem too.
What you need is this:
http://doc.qt.io/qbs/jsextension-process.html
I'm not sure what your end goal is but you could use Transformer{} instead of a Rule{}. The biggest difference between a Rule{} and a Transformer{} is you don't need any inputs for the Transformer{} to run.
Also see Transformer.alwaysRun property.
https://doc.qt.io/qbs/transformer-item.html
As part of my project, I need to read files from a directory and do some operations all these in build script. For each file, the operation is the same(reading some SQL queries and execute it). I think its a repetitive task and better to write inside a method. Since I'm new to Gradle, I don't know how it should be. Please help.
One approach given below:
ext.myMethod = { param1, param2 ->
// Method body here
}
Note that this gets created for the project scope, ie. globally available for the project, which can be invoked as follows anywhere in the build script using myMethod(p1, p2) which is equivalent to project.myMethod(p1, p2)
The method can be defined under different scopes as well, such as within tasks:
task myTask {
ext.myMethod = { param1, param2 ->
// Method body here
}
doLast {
myMethod(p1, p2) // This will resolve 'myMethod' defined in task
}
}
If you have defined any methods in any other file *.gradle - ext.method() makes it accessible project wide. For example here is a
versioning.gradle
// ext makes method callable project wide
ext.getVersionName = { ->
try {
def branchout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
standardOutput = branchout
}
def branch = branchout.toString().trim()
if (branch.equals("master")) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
return stdout.toString().trim()
} else {
return branch;
}
}
catch (ignored) {
return null;
}
}
build.gradle
task showVersion << {
// Use inherited method
println 'VersionName: ' + getVersionName()
}
Without ext.method() format , the method will only be available within the *.gradle file it is declared. This is the same with properties.
You can define methods in the following way:
// Define an extra property
ext.srcDirName = 'src/java'
// Define a method
def getSrcDir(project) {
return project.file(srcDirName)
}
You can find more details in gradle documentation Chapter 62. Organizing Build Logic
An example with a root object containing methods.
hg.gradle file:
ext.hg = [
cloneOrPull: { source, dest, branch ->
if (!dest.isDirectory())
hg.clone(source, dest, branch)
else
hg.pull(dest)
hg.update(dest, branch)
},
clone: { source, dest, branch ->
dest.mkdirs()
exec {
commandLine 'hg', 'clone', '--noupdate', source, dest.absolutePath
}
},
pull: { dest ->
exec {
workingDir dest.absolutePath
commandLine 'hg', 'pull'
}
},
]
build.gradle file
apply from: 'hg.gradle'
hg.clone('path/to/repo')
Somehow, maybe because it's five years since the OP, but none of the
ext.someMethod = { foo ->
methodBody
}
approaches are working for me. Instead, a simple function definition seems to be getting the job done in my gradle file:
def retrieveEnvvar(String envvar_name) {
if ( System.getenv(envvar_name) == "" ) {
throw new InvalidUserDataException("\n\n\nPlease specify environment variable ${envvar_name}\n")
} else {
return System.getenv(envvar_name)
}
}
And I call it elsewhere in my script with no prefix, ie retrieveEnvvar("APP_PASSWORD")
This is 2020 so I'm using Gradle 6.1.1.
#ether_joe the top-voted answer by #InvisibleArrow above does work however you must define the method you call before you call it - i.e. earlier in the build.gradle file.
You can see an example here. I have used this approach with Gradle 6.5 and it works.
With Kotlin DSL (build.gradle.kts) you can define regular functions and use them.
It doesn't matter whether you define your function before the call site or after it.
println(generateString())
fun generateString(): String {
return "Black Forest"
}
tasks.create("MyTask") {
println(generateString())
}
If you want to import and use a function from another script, see this answer and this answer.
In my react-native in build.gradle
def func_abc(y){return "abc"+y;}
then
def x = func_abc("y");
If you want to check:
throw new GradleException("x="+x);
or
println "x="+x;