80

I am working on a Gradle script where I need to read the local.properties file and use the values in the properties file in build.gradle. I am doing it in the below manner. I ran the below script and it is now throwing an error, but it is also not doing anything like creating, deleting, and copying the file. I tried to print the value of the variable and it is showing the correct value.

Can someone let me know if this is the correct way to do this? I think the other way is to define everything in the gradle.properties and use it in the build.gradle. Can someone let me know how could I access the properties in build.gradle from build.properties?

build.gradle file:

apply plugin: 'java'

// Set the group for publishing
group = 'com.true.test'

/**
 * Initializing GAVC settings
 */
def buildProperties = new Properties()
file("version.properties").withInputStream {
        stream -> buildProperties.load(stream)
}
// If jenkins build, add the jenkins build version to the version. Else add snapshot version to the version.
def env = System.getenv()
if (env["BUILD_NUMBER"]) buildProperties.test+= ".${env["BUILD_NUMBER"]}"
version = buildProperties.test
println "${version}"

// Name is set in the settings.gradle file
group = "com.true.test"
version = buildProperties.test
println "Building ${project.group}:${project.name}:${project.version}"

Properties properties = new Properties()
properties.load(project.file('build.properties').newDataInputStream())
def folderDir = properties.getProperty('build.dir')
def configDir = properties.getProperty('config.dir')
def baseDir  = properties.getProperty('base.dir')
def logDir  = properties.getProperty('log.dir')
def deployDir  = properties.getProperty('deploy.dir')
def testsDir  = properties.getProperty('tests.dir')
def packageDir  = properties.getProperty('package.dir')
def wrapperDir  = properties.getProperty('wrapper.dir')


sourceCompatibility = 1.7
compileJava.options.encoding = 'UTF-8'

repositories {
     maven { url "http://arti.oven.c:9000/release" }
  }

task swipe(type: Delete) {
         println "Delete $projectDir/${folderDir}"
         delete "$projectDir/$folderDir"
         delete "$projectDir/$logDir"
         delete "$projectDir/$deployDir"
         delete "$projectDir/$packageDir"
         delete "$projectDir/$testsDir"
         mkdir("$projectDir/${folderDir}")
         mkdir("projectDir/${logDir}")
         mkdir("projectDir/${deployDir}")
         mkdir("projectDir/${packageDir}")
         mkdir("projectDir/${testsDir}")
}
task prepConfigs(type: Copy, overwrite:true, dependsOn: swipe) {
    println "The name of ${projectDir}/${folderDir} and ${projectDir}/${configDir}"
    from('${projectDir}/${folderDir}')
    into('${projectDir}/$configDir}')
    include('*.xml')
}

build.properties file:

# -----------------------------------------------------------------
# General Settings
# -----------------------------------------------------------------
application.name  = Admin
project.name = Hello Cool

# -----------------------------------------------------------------
# ant build directories
# -----------------------------------------------------------------
sandbox.dir = ${projectDir}/../..
reno.root.dir=${sandbox.dir}/Reno
ant.dir = ${projectDir}/ant
build.dir = ${ant.dir}/build
log.dir  = ${ant.dir}/logs
config.dir = ${ant.dir}/configs
deploy.dir  = ${ant.dir}/deploy
static.dir =  ${ant.dir}/static
package.dir = ${ant.dir}/package
tests.dir = ${ant.dir}/tests
tests.logs.dir = ${tests.dir}/logs
external.dir = ${sandbox.dir}/FlexCommon/External
external.lib.dir = ${external.dir}/libs
Mahozad
  • 18,032
  • 13
  • 118
  • 133
unknown
  • 1,815
  • 3
  • 26
  • 51
  • 1
    Possible duplicate of [Gradle - Include Properties File](http://stackoverflow.com/questions/11749384/gradle-include-properties-file) – JDL Feb 10 '17 at 18:54

5 Answers5

137

If using the default gradle.properties file, you can access the properties directly from within your build.gradle file:

gradle.properties:

applicationName=Admin
projectName=Hello Cool

build.gradle:

task printProps {
    doFirst {
        println applicationName
        println projectName
    }
}

If you need to access a custom file, or access properties which include . in them (as it appears you need to do), you can do the following in your build.gradle file:

def props = new Properties()
file("build.properties").withInputStream { props.load(it) }

task printProps {
    doFirst {
        println props.getProperty("application.name")
        println props.getProperty("project.name")
    }
}

Take a look at this section of the Gradle documentation for more information.

Edit

If you'd like to dynamically set up some of these properties (as mentioned in a comment below), you can create a properties.gradle file (the name isn't important) and require it in your build.gradle script.

properties.gradle:

ext {
    subPath = "some/sub/directory"
    fullPath = "$projectDir/$subPath"
}

build.gradle

apply from: 'properties.gradle'

// prints the full expanded path
println fullPath
mkobit
  • 43,979
  • 12
  • 156
  • 150
blacktide
  • 10,654
  • 8
  • 33
  • 53
  • I can access the value of projectDir directly in gradle script.Can you please let me know if I have a value in properties file like this renosandbox.dir = $projectDir/../.. and I tried to access this in my gradle script def Pathdir = props.getProperty('renosandbox.dir') println "${Pathdir}/${folder}" in my task.Do you think it will expand the value of ProjectDir? – unknown May 08 '16 at 17:15
  • No, it won't expand it automatically. You would need to prepend your property with `projectDir` like so: `def pathDir = "$projectDir/${props.getProperty('renosandbox.dir')}` – blacktide May 08 '16 at 17:36
  • @Sushant Take a look at the edit for another way to do what you're asking. – blacktide May 08 '16 at 17:41
  • 1
    Thaks for giving me the right direction and providing me the information of reading the properties file in various ways. – unknown May 08 '16 at 19:05
  • Thank you! This helped me solve what was missing in the gradle.properties file so I could run it from the command line. – rray Apr 11 '17 at 15:33
21

We can use a separate file (config.groovy in my case) to abstract out all the configuration.

In this example, we're using three environments viz.,

  1. dev
  2. test
  3. prod

which has properties serverName, serverPort and resources. Here we're expecting that the third property resources may be same in multiple environments and so we've abstracted out that logic and overridden in the specific environment wherever necessary:

config.groovy

resources {
    serverName = 'localhost'
    serverPort = '8090'
}

environments {
    dev {
        serverName = 'http://localhost'   
        serverPort = '8080'
    }

    test {
        serverName = 'http://www.testserver.com'
        serverPort = '5211'
        resources {
            serverName = 'resources.testserver.com'
        }
    }

    prod {
        serverName = 'http://www.productionserver.com'
        serverPort = '80'
        resources {
            serverName = 'resources.productionserver.com'
            serverPort = '80'
        }
    }
}

Once the properties file is ready, we can use the following in build.gradle to load these settings:

build.gradle

loadProperties()

def loadProperties() {
    def environment = hasProperty('env') ? env : 'dev'
    println "Current Environment: " + environment

    def configFile = file('config.groovy')
    def config = new ConfigSlurper(environment).parse(configFile.toURL())
    project.ext.config = config
}

task printProperties {
    println "serverName:  $config.serverName"
    println "serverPort:  $config.serverPort"
    println "resources.serverName:  $config.resources.serverName"
    println "resources.serverPort:  $config.resources.serverPort"
}

Let's run these with different set of inputs:

  1. gradle -q printProperties

    Current Environment: dev
    serverName:  http://localhost
    serverPort:  8080
    resources.serverName:  localhost
    resources.serverPort:  8090
    
  2. gradle -q -Penv=dev printProperties

    Current Environment: dev
    serverName:  http://localhost
    serverPort:  8080
    resources.serverName:  localhost
    resources.serverPort:  8090
    
  3. gradle -q -Penv=test printProperties

    Current Environment: test
    serverName:  http://www.testserver.com
    serverPort:  5211
    resources.serverName:  resources.testserver.com
    resources.serverPort:  8090
    
  4. gradle -q -Penv=prod printProperties

    Current Environment: prod
    serverName:  http://www.productionserver.com
    serverPort:  80
    resources.serverName:  resources.productionserver.com
    resources.serverPort:  80
    
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
3

Another way... in build.gradle:

Add :

classpath 'org.flywaydb:flyway-gradle-plugin:3.1'

And this :

def props = new Properties()
file("src/main/resources/application.properties").withInputStream { props.load(it) }
apply plugin: 'flyway'
flyway {
    url = props.getProperty("spring.datasource.url")
    user = props.getProperty("spring.datasource.username")
    password = props.getProperty("spring.datasource.password")
    schemas = ['db_example']
}
Bruno
  • 3,872
  • 4
  • 20
  • 37
1

Just had this issue come up today. We found the following worked both locally and in our pipeline:

In build.gradle:

try {
  apply from: 'path/name_of_external_props_file.properties'
} catch (Exception e) {}

This way when an external props file which shouldn't get committed to Git or whatever (as in our case) you are using is not found in the pipeline, this 'apply from:' won't throw an error in it. In our use case we have a file with a userid and password that should not get committed to Git. Aside from the problem of file-reading: we found that the variables we had declared in the external file, maven_user and maven_pass, had in fact to be declared in gradle.properties. That is they simply needed to be mentioned as in:

projectName=Some_project_name
version=1.x.y
maven_user=
maven_pass=

We also found that in the external file we had to put single-quotes around these values too or Gradle got confused. So the external file looked like this:

maven_user='abc123'
maven_pass='fghifh7435bvibry9y99ghhrhg9539y5398'

instead of this:

maven_user=abc123
maven_pass=fghifh7435bvibry9y99ghhrhg9539y5398

That's all we had to do and we were fine. I hope this may help others.

Matt Campbell
  • 1,967
  • 1
  • 22
  • 34
0

This is for Kotlin DSL (build.gradle.kts):

import java.util.*
// ...

val properties = Properties().apply {
    load(rootProject.file("my-local.properties").reader())
}
val prop = properties["myPropName"]

In Android projects (when applying the android plugin) you can also do this:

import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
// ...

val properties = gradleLocalProperties(rootDir)
val prop = properties["propName"]
Mahozad
  • 18,032
  • 13
  • 118
  • 133