Gradle build pick respective file and rename that file from sub project based on parameter and make zip for upload to archiva

We have subfolderA under root project.
subfolderA has build.gradle file like below given.
currently we are making subfolderA.zip and uploading same to archiva.
subfolderA contains below folder structure.
subfolderA
|
conf and log

conf folder has 2 files conf.qa and conf.uat . Currently i am zipping both files.

Now, i want to make subfolderA.zip file with any one of conf file either conf.qa or conf.uat then rename file as conf. I am planning to provide some parameter from jenkins or gradle command to pick up right file and rename that file then upload zip o archiva.
Could you please suggest to achieve this requirement.

subfodlerA build.gradle file:
command: gradle build uploadArchives

apply plugin: ‘distribution’

distributions {
main {
baseName = ‘subfolderA’
contents {
from ‘…/subfolderA’
}
}
}

tasks.distTar.enabled = false

configurations.archives.with {
artifacts.remove artifacts.find { it.file =~ ‘tar’ }
artifacts.remove artifacts.find { it.file =~ ‘jar’ }
}

uploadArchives {
repositories.mavenDeployer {
repository(url: “http://archivaurl/$System.env.JOB_NAME/”) {authentication(userName: “usr”, password: “pwd”)}
pom.artifactId=“subfolderA”
pom.version = “$System.env.BUILD_NUMBER”
pom.groupId = ‘project’
}
}

Hi,

Have you ever considered filtering your configuration file?

Define a default environment in gradle.properties:

me@laptop:/tmp/foobar$ cat gradle.properties 
env = qa

Define a filter file (here I’ll take a groovy based dsl, you could pick xml or property files as long as you can obtain a Map easily):

me@laptop:/tmp/foobar$ cat src/main/filters/environments.groovy 
all {
	name = 'something'
}

environments {
	qa {
		commit = false
		port = 8080
	}

	uat {
		commit = true
		port = 443
	}
}

Use placeholders to inject values in conf:

me@laptop:/tmp/foobar$ cat src/main/config/conf 
name = ${all.name}
port = ${port}
commit = ${commit}

A little bit of magic to glu everything:

plugins {
	id 'distribution'
}

distributions {
	main {
		contents {
			from('src/main/config') {
				expand(new ConfigSlurper(env).parse(file("src/main/filters/environments.groovy").text))
			}
		}
	}
}

To build packages:

me@laptop:/tmp/foobar$ gradle clean assemble # package with qa values
me@laptop:/tmp/foobar$ gradle clean assemble -Penv=uat # uat values

Note that if expand does not suit you, you can replace it with:
filter org.apache.tools.ant.filters.ReplaceTokens, beginToken: '${', endToken: '}', tokens: values where values must be an Hashtable of String keys mapping String values (null not permitted).

Hi,

Thank you for reply.
I just created filter and did same what you mentioned. I am getting below error. Am i missing something here?

Could not add file ‘/apps/TESTING/projectA/bin/test.sh’ to ZIP

My gradle file:

distributions {
main {
baseName = ‘projectA’
contents {
from (’…/projectA’){
expand(new ConfigSlurper(env).parse(file(“filters/environments.groovy”).text))
}
}
}
}

Hi,

When using filtering with expand Gradle uses the SimpleTemplateEngine from Groovy to inject values in file. Any expression like $foobar or ${foobar ?: 'default value'} or ${1 + 1} is evaluated using Groovy engine. Your issue is that you filter more files than I did in my example and the shell files generated by the distribution plugin contains a lot of dollar signs to use environment variables that are understood as Groovy variables by expand.

Either use filter instead of expand, or better in my opinion, reduce the scope of files to filter:

distributions {
    main {
        contents {
            from ('src/main/config') {
                filesMatching('**/conf') {
                    expand /* ... */
                }
            }
        }
    }
}

On a side note, I would not add a whole subproject in the from. It brings the subprojectA/build tree structure in your distribution, but that tree structure may change when updating or downgrading Gradle. As a result your distribution will be less robust than something based on source directories only.

Maybe you should consider to move the distribution plugin to subprojectA or move the file from subprojectA to the root project. If neither are possible, then maybe drop a Copy task copying the conf file from subprojectA to a temporary directory in the rootproject before packaging your distribution.

1 Like

Hi,

Thank you for pushed me on right track. Now, it is working as you said i am filtering one file ‘conf’.
And to avoid subprojectA/build tree, i have other folder called subprojectA-gradle where build.gradle file kept. I am not sure this is standard way. But, it was there since long time and i was used same structure.

Hi,

Could you please suggest How to filter two different values of single property for single environment block?

we have prod block in environments.groovy filter file.

prod {

         URL = 'url'
         J
    }

we have two different url’s for URL property. we need to fetch/filter two different values for two different sub projects from environments.groovy file for prod.
URL=${URL}
We have single config.prop for all sub projects.
For instance, subproject1.zip file should have config.prop file with below property
URL=url1
subproject2.zip file should have config.prop file with below property
URL=url2

Hi,

I’d create a second configuration file, create a second ConfigObject with ConfligSlurper.parse and merge both objects in a single map. Something like that more or less:

ConfigSlurper slurper = new ConfigSlurper(env)
expand slurper.parse(basefile).merge(slurper.parse(urlfile))