Load property from external file into build.gradle - groovy

I have this:
def loadProperties(String sourceFileName) {
def config = new Properties()
def propFile = new File(sourceFileName)
if (propFile.canRead()) {
config.load(new FileInputStream(propFile))
for (Map.Entry property in config) {
ext[property.key] = property.value;
}
}
}
loadProperties 'gradle.properties'
How do I reference the property (ndk.dir) in build.gradle?
def ndkBuild = new File("$ndk.dir", 'ndk-build')
And is there a better way of reading ndk.dir from file gradle.properties?
And how do I use it in?
def ndkBuild = new File("$ndk.dir", 'ndk-build')
Full code:
task buildNative(type: Exec) {
loadProperties 'gradle.properties'
if (System.getenv('NDK_HOME') != null || "$ndk.dir" != null) {
if ("$ndk.dir" != null) {
def ndkBuild = new File("$ndk.dir", 'ndk-build')
} else {
def ndkBuild = new File(System.getenv('NDK_HOME'), 'ndk-build')
}
workingDir "jni"
executable ndkBuild
} else {
throw new GradleException('Reason: NDK_HOME not set or ndk.dir is missing in gradle.properties...')
}
}
def loadProperties(String sourceFileName) {
def config = new Properties()
def propFile = new File(sourceFileName)
if (propFile.canRead()) {
config.load(new FileInputStream(propFile))
for (Map.Entry property in config) {
ext[property.key] = property.value;
}
}
}

Just like ndk.dir, "$ndk.dir" first gets the ndk property, and then the dir property, which is not what you want. (This is also evident in the error message, which says "Could not find property 'ndk'".) Instead, this should work:
def ndkBuild = new File(project.property('ndk.dir'), 'ndk-build')
A safer solution is to store the whole Properties object as a single extra property:
...
ext.externalProps = config
Then you can access external properties like so:
def ndkBuild = new File(externalProps['ndk.dir'], 'ndk-build')

Related

Groovy String return type with instantiation

This is my class where I am reading an properties file there are two files Config.groovy where I have the method and Call.groovy where I am calling the method from config and expecting an return.
Config.groovy
class Config
{
public methodParse {
Properties properties = new Properties()
File propertiesFile = new File('src/main/resources/application.properties')
propertiesFile.withInputStream
{
properties.load(it)
}
String value = properties."$name"
return value
}
}
load.groovy
def config = new Config ()
config.methodParse "environments.local.logfile"
println (config.methodParse());
How do I have load.groovy pass an parameter and then print what is received?
Ignoring the syntax errors
You could try something like
class Config
{
public String methodParse (String name)
{
Properties properties = new Properties()
File propertiesFile = new File('src/main/resources/application.properties')
propertiesFile.withInputStream
{
properties.load(it)
}
String value = properties."$name"
return value
}
}
def config = new Config ()
the_value =config.methodParse("environments.local.logfile")
println (conf_value);
What if I understand you correctly.
class Config {
public methodParse(String name) {
Properties properties = new Properties()
File propertiesFile = new File('src/main/resources/application.properties')
propertiesFile.withInputStream {
properties.load(it)
}
properties."$name"
}
}
Usage:
def config = new Config ()
config.methodParse "environments.local.logfile"
I was able to fix it this is what I did
def config = new Config ()
String conf_value = config.methodParse("environments.local.logfile")
println conf_value

Groovy Half-mock with MockFor

I want to test the following class:
public class DBSync {
public dbNotify( String path ) {
if (!path) {
return
}
def pathIndex = path.lastIndexOf(File.separator)
if (pathIndex > 0) {
def folder = path[0..pathIndex - 1]
def fileName = path[pathIndex + 1..path.length() - 1]
println "Syncing from directory $folder for filename $fileName"
if (fileName.contains(EXCLUDE_FILE_PATTERN)) {
println "Filename is $EXCLUDE_FILE_PATTERN skipping db write "
return
}
writeToDB(folder, fileName)
}
}
public writeToDB ( folder, file ) {
// inserting to database
}
}
The test class is:
public class TestDBSync {
#Test
public void test() {
def dbSyncContext = new MockFor(DBSync)
def file = "file.zip"
def folder = "data"
def path = folder + File.separator + file
def called = false
// Expect at least one call
mockDBSyncContext.demand.writeToDB(1..1) { String folderargs, String fileargs -> called = true }
mockDBSyncContext.demand.dbNodify(1..1) { String pathargs -> return }
// Obtaining a usuable mock instance
def mockDBSyncProxy = mockDBSyncContext.proxyInstance()
// Fake calling the method
mockDBSyncContext.use {
mockDBSyncProxy.dbNotify(path )
}
// Verify invoked at least once?
mockDBSyncContext.verify(mockDBSyncProxy)
}
}
The test is failing and I am getting the following error:
junit.framework.AssertionFailedError: No call to 'dbNotify' expected
at this point. Still 1 call(s) to 'writeToDB' expected.

groovy print environments from groovy.config

how do I print available environments from a config file? What is the form of the ojbect ConfigSlurper creates?
I tried
def config2 = new ConfigSlurper().parse(new File('obieeadmincfg.groovy').toURL())
config2.config.environments.each { println ${it} }
and
println prettyPrint(toJson(config2))
and
for ( i in 0 ..config2.config.environments.size()-1)
println config2.config.environments[i]
groovy.config
//Config3.groovy
obieadmin {
//default values
serverurl = "http://default.mycompany.com"
}
environments {
pldev01 {
obieeadmin {
serverurl = 'devgdwobi03.x.com'
}
}
plsbx02 {
obieeadmin {
serverurl = 'devgdwobi03.x.com'
}
}
}
I'm afraid you can't do this out-of box.
But using a bit of Groovy Metaprogramming it's achievable.
Groovy config slurper parses proper Groovy file, and you can do the same with GroovyShell. You can catch call to environment method providing closure in binding. In that closure you have to collect all top-level method calls(with same methodMissing).
Providing base script with property and method missing handlers, you can suppress runtime errors, and execute script without much care to other properties.
Not the nicest path, but it works.
package test
import org.codehaus.groovy.control.CompilerConfiguration
class A extends Script {
def propertyMissing(String name) { null }
def propertyMissing(String name, def arg) {}
def methodMissing(String name, def args) {}
#Override Object run() { null }
}
class NameCollector {
def envs = []
def methodMissing(String name, def args) { envs << name }
}
// configure interceptors.
def configuration = new CompilerConfiguration()
configuration.scriptBaseClass = 'test.A'
def nc = new NameCollector()
def environments = { Closure it ->
it.delegate = nc;
it.resolveStrategy = Closure.DELEGATE_ONLY
it()
}
// execute config script
new GroovyShell([environments: environments] as Binding, configuration).evaluate(new File("config.groovy"))
nc.envs // Return, print them.
Not sure if this is going to work forever but currently you can do it by overriding the setting for the 'environments' conditional block, like this:
def config = """environments {
dev {
foo = "bar"
}
prod {
foo = "baz"
}
}"""
def configSlurper = new ConfigSlurper()
configSlurper.registerConditionalBlock('environments', null)
assert configSlurper.parse(config).environments.keySet() == ['dev', 'prod'].toSet()

Scan directories in groovy with ant builder file scanner

I want to use fileScanner of AntBuilder to go over directories.
My code looks like:
scanner = new AntBuilder().fileScanner {
fileset(dir:sourcedir, casesensitive:false) {
include(name:pattern)
type(type:'dir')
}
}
I want to loop with the scanner just on directories, for example:
for (file in scanner) {
assert file.directory == true
}
Any idea ?
Thanks!!!!!!!!
Here's how to do it with fileScanner
scanner = new AntBuilder().fileScanner {
fileset(dir:sourcedir, casesensitive:false) {
include(name:pattern)
}
}
// Just the directories
scanner.directories().each {
println it.name
}
You could also do it with Groovy calls:
def dirs = []
new File( sourcedir ).eachDirRecurse {
// Check the name here, obviously the Ant pattern you have probably won't work
if( it.name ==~ pattern ) dirs << it
}
dirs.each {
println it.name
}

How to add a new closure to a class in groovy

From Snipplr
Ok here is the script code, in the comments is the question and the exception thrown
class Class1 {
def closure = {
println this.class.name
println delegate.class.name
def nestedClos = {
println owner.class.name
}
nestedClos()
}
}
def clos = new Class1().closure
clos.delegate = this
clos()
//Now I want to add a new closure to Class1
def newClosure = {
println "new Closure"
println this.class.name
println delegate.class.name
def nestedClos = {
println owner.class.name
}
nestedClos()
}
//getAbc to create a property, not a method
Class1.metaClass.getAbc = newClosure
//What happens here is that the property abc is not used as a closure per se, it's used
//as a property and when I execute it just run the closure and when I want to change
//the delegate, a null pointer is thrown
clos = new Class1().abc //abc executed instead of passing the reference closure
clos.delegate = this //Exception!!!!
clos()
Ok, It's done it's not a fancy way, but I have the solution....yeah!
Create the property as object and later assign the closure
class Class1 {
def closure = {
println this.class.name
println delegate.class.name
def nestedClos = {
println owner.class.name
}
nestedClos()
}
}
def clos = new Class1().closure
clos.delegate = this
clos()
//Now I want to add a new closure to Class1
def newClosure = {
println "new Closure"
println this.class.name
println delegate.class.name
def nestedClos = {
println owner.class.name
}
nestedClos()
}
//before edit
//Class1.metaClass.abc = new Object()
Class1.metaClass.abc = newClosure
def cl = new Class1()
//Before edit
//For the sake of simplicity we are going to use & for the method
//clos = cl.abc
closs = cl.&abc
clos.delegate = this
clos()

Resources