Gradle Dynamically Generate Tasks - gradle

This is my first attempt using clojure and I'm attempting to generate some tasks in my build.gradle file. I'm encountering complication errors such as:
* Where:
Build file '/Users/austin/Repositories/test/build.gradle' line: 47
* What went wrong:
A problem occurred evaluating root project 'test'.
Cannot set the value of read-only property 'src' for task ':downloadDriverfirefox' of type de.undercouch.gradle.tasks.download.Download.
I'm fairly certain it's just my inexperience with the groovy language, but I could really use some pointers as to where I'm going wrong.
ext {
// The drivers we want to use
drivers = ["firefox", "chrome"]
driversSrc = [:]
driversSrc['firefox'] = 'https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-macos.tar.gz'
driversSrc['chrome'] = 'https://chromedriver.storage.googleapis.com/2.29/chromedriver_mac64.zip'
driverDest = new File("${buildDir}/webdrivers")
}
import org.gradle.api.tasks.*
import de.undercouch.gradle.tasks.download.Download
driversSrc.each { driver, path ->
tasks.create(name: 'downloadDriver'+"${driver}", type: Download) {
src = path
dest ext.driverDest
overwrite true
}
}
driversSrc.each {driver ->
tasks.create(name: 'unzipDriver'+"${driver}", dependsOn: 'downloadDriver'+"${driver}", type: Copy) {
from zipTree(file('downloadDriver'+"${driver}").dest)
into buildDir/'webdrivers'
}
}

Things I have done:
Cleaned up map to store data
Since you are using this plugin: https://github.com/michel-kraemer/gradle-download-task, I had to make sure the tasks were used correctly
Since you have a tar, you have to use tarTree as well as zipTree
Please try this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "de.undercouch:gradle-download-task:3.2.0"
}
}
allprojects {
repositories {
jcenter()
}
}
import de.undercouch.gradle.tasks.download.Download
apply plugin: "de.undercouch.download"
ext {
driversSrc = [
"firefox": "https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-macos.tar.gz",
"chrome" : "https://chromedriver.storage.googleapis.com/2.29/chromedriver_mac64.zip"
]
driverDest = "${buildDir}/webdrivers"
}
driversSrc.each { driver, path ->
def fileDest = new File(driverDest, new File(path).getName())
tasks.create(name: "downloadDriver${driver}", type: Download) {
src path
dest fileDest
overwrite true
}
tasks.create(name: "unzipDriver${driver}", dependsOn: "downloadDriver${driver}", type: Copy) {
from path.endsWith("zip") ? zipTree(file(fileDest)) : tarTree(file(fileDest))
into driverDest
}
}
To run the tasks:
./gradlew unzipDriverfirefox unzipDriverchrome*

Related

Use of Gradle Plugin in external .gradle file

Background:
I'm trying to use the gradle-dependency-graph-generator-plugin in a gradle build, and configure it with custom Generator configurations. When I place the configuration within the _root.gradle, our root gradle project:
buildscript {
repositories {
maven {
url artifactoryRepoURL + '/repo'
}
}
dependencies {
//...
classpath "com.vanniktech:gradle-dependency-graph-generator-plugin:0.5.0"
}
}
//...
allprojects {
//...
apply plugin: "com.vanniktech.dependency.graph.generator"
//...
}
...it works just fine. (Though, Intellij reports errors in the import, it builds and runs both on command line and in the IDE)
The Problem
I'd like to put this code in a separate gradle file, just so it's not cluttering up the root project. So I move the code to a dependencyGraph.gradle file, and include it with an
apply from: "$rootProject.projectDir/dependencyGraph.gradle"
However, I get compilation errors, class not found. So I add the buildScript and dependencies/classpath from the root project file, and try again. This time, it gives a class cast exception:
com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension$Generator cannot be cast to com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension$Generator
Its the same classname, so I assume this is some kind of classloader problem. So, how does one include a build script that references plugin classes into a project.gradle?
EDIT:
Per – #EugenMartynov 's comment, the file looks like:
buildscript {
repositories {
maven {
url artifactoryRepoURL + '/repo'
}
}
dependencies {
classpath "com.vanniktech:gradle-dependency-graph-generator-plugin:0.5.0"
}
}
import com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorPlugin
import com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension.Generator
import guru.nidi.graphviz.attribute.Color
import guru.nidi.graphviz.attribute.Style
import guru.nidi.graphviz.attribute.Label
def updateNode(node, dependency) {
def group = dependency.getModuleGroup()
def colorCodeFor = { starts, color ->
if (group.startsWith(starts)) {
node.add(Style.FILLED, Color.rgb(color))
return color
}
return null
}
def color = colorCodeFor("commons", "#ff008c")
?: colorCodeFor("org.apache", "#ff008c")
?: colorCodeFor("org.springframework", "#6db33f")
?: colorCodeFor("javax", "#ff0000")
?: colorCodeFor("com.fasterxml", "#3a772e")
?: colorCodeFor("ch.qos.logback", "#ffd0a0")
?: colorCodeFor("", String.format("#%06x", Math.abs(group.hashCode()) % (255*255*255))) // base off the group
return node
}
def colorCodedGenerator = new Generator(
"ColorCoded", // Suffix for our Gradle task.
{ dependency -> true }, // filter
{ dependency -> true }, // Include transitive dependencies.
{ node, dependency -> updateNode(node, dependency) }, // Give them some color.
{ node, project ->node.add(Style.FILLED, Color.rgb("#2cc2e4")) }, // project nodes.
)
dependencyGraphGenerator {
generators = [ Generator.ALL, colorCodedGenerator ]
}
and is applied within the allprojects block:
allprojects {
...
apply plugin: "com.vanniktech.dependency.graph.generator"
apply from: "$rootProject.projectDir/dependencyGraph.gradle"
...
}
though I also tried only within the root project. As configured, I get:
FAILURE: Build failed with an exception.
...
* What went wrong:
A problem occurred configuring root project 'dar'.
> com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension$Generator cannot be cast to com.vanniktech.dependency.graph.generator.DependencyGraphGeneratorExtension$Generator
This is gradle 4.9, btw

I got an error using this build.grafle file and don't know how to fix it

Here's the Error:
FAILURE: Build failed with an exception.
Where: Build file '/home/wieland/GitGradlePackaging/build.gradle' line: 22
What went wrong: A problem occurred evaluating root project 'GitGradlePackaging'.
Could not get unknown property 'org' for object of type org.gradle.api.internal.initialization.DefaultScriptHandler.
And Here's my build.gradle File:
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* user guide available at https://docs.gradle.org/4.6/userguide/tutorial_java_projects.html
*/
//From example: http://mrhaki.blogspot.co.at/2015/04/gradle-goodness-use-git-commit-id-in.html
buildscript {
repositories {
jcenter()
}
dependencies {
//Add dependencies for build script, so we can access Git from our build script
classpath 'org.ajoberstar:grgit:1.1.0'
}
def git = org.ajoberstar.grgit.Grgit.open(file('.'))
//To save Githash
def githash = git.head().abbreviatedId
}
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building an application
id 'application'
// Apply the groovy plugin to also add support for Groovy (needed for Spock)
id 'groovy'
id 'distribution'
}
// Set version
project.version = mainProjectVersion + " - " + githash
project.ext.set("wholeVersion", "$project.version - $githash")
project.ext.set("buildtimestamp", "2000-01-01 00:00")
def versionfilename = "versioninfo.txt"
def GROUP_DEBUG = 'Debug'
// Task to print project infos
task debugInitialSettings {
group = GROUP_DEBUG
doLast {
println 'Version: ' + project.wholeVersion
println 'Timestamp: ' + project.buildtimestamp
println 'Filename: ' + project.name
}
}
// To add the githash to zip
task renameZip {
doLast {
new File ("$buildDir/distributions/$project.name-${project.version}.zip")
.renameTo ("$buildDir/distributions/$project.name-${project.wholeVersion}.zip")
}
}
distZip.finalizedBy renameZip
// To add the githash to tar
task renameTar{
doLast {
new File ("$buildDir/distributions/$project.name-${project.version}.tar")
.renameTo ("$buildDir/distributions/$project.name-${project.wholeVersion}.tar")
}
}
distTar.finalizedBy renameTar
// Define the main class for the application
mainClassName = 'App'
dependencies {
// This dependency is found on compile classpath of this component and consumers.
compile 'com.google.guava:guava:23.0'
// Use the latest Groovy version for Spock testing
testCompile 'org.codehaus.groovy:groovy-all:2.4.13'
// Use the awesome Spock testing and specification framework even with Java
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
testCompile 'junit:junit:4.12'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
//To generate Testreports as HTML
test {
reports {
junitXml.enabled = false
html.enabled = true
}
}
distributions {
main {
contents {
from { 'build/docs' }
into ('reports') {
from 'build/reports'
}
}
}
}
//To make sure that test and javadoc ran before zip and tar
distTar.dependsOn test
distZip.dependsOn test
distTar.dependsOn javadoc
distZip.dependsOn javadoc
Please keep in mind I have not much knowledge about gradle as I'm just starting to learn it!
Thanks in advance :)
You have to move the githash definition outside the buildscript block
buildscript {
repositories {
jcenter()
}
dependencies {
//Add dependencies for build script, so we can access Git from our build script
classpath 'org.ajoberstar:grgit:1.1.0'
}
}
def git = org.ajoberstar.grgit.Grgit.open(file('.'))
//To save Githash
def githash = git.head().abbreviatedId
The reason is that when the buildscript block is evaluated line by line, its dependencies are not yet loaded. When the rest of the script is evaluated, the dependencies of the buildscript block have already been loaded. This is actually the reason for the buildscript block existence: to be run before the rest of the build and prepare the setup.

Gatling running multiple simulations with Gradle plugin

The Gradle plugin (https://github.com/commercehub-oss/gatling-gradle-plugin, v2.1) claims The ability to configure multiple simulations per gradle project
Given the following gradle file:
apply plugin: 'scala'
group '****'
version '1.0-SNAPSHOT'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.commercehub:gatling-gradle-plugin:2.1'
}
}
repositories {
jcenter()
}
ext {
SCALA_VERSION = "2.11.7"
GATLING_VERSION = "2.2.3"
}
dependencies {
compile "org.scala-lang:scala-library:${SCALA_VERSION}"
testCompile 'com.typesafe:config:1.3.1'
testCompile "io.gatling.highcharts:gatling-charts-highcharts:${GATLING_VERSION}"
testCompile "io.gatling:gatling-test-framework:${GATLING_VERSION}"
}
apply plugin: 'gatling'
import com.commercehub.gradle.plugin.GatlingTask
task loadTest(type: GatlingTask, dependsOn: ['testClasses']) {
gatlingSimulation = 'HealthSimulation,PlaceAttributesSimulation'
jvmOptions {
jvmArgs = [
"-Dlogback.configurationFile=${logbackGatlingConfig()}",
"-Denv=${System.getProperty('env', 'stg')}",
]
minHeapSize = "1024m"
maxHeapSize = "1024m"
}
}
def logbackGatlingConfig() {
return sourceSets.test.resources.find { it.name == 'logback-gatling.xml' }
}
in particular the line gatlingSimulation = 'HealthSimulation,PlaceAttributesSimulation', I would expect both simulation to be run. Why? Because looking at the Gradle plugin, gatlingSimulation is then passed to Gatling -s flag.
Long story short, Gatling -s does not support multiple simulations anymore (see https://github.com/gatling/gatling/issues/363 for details), so I think I am missing a bit in the gradle plugin I am using to enable multiple simulations.
Both simulations run fine when run individually, but if I try to run them together, Gatling stucks asking which one to execute. Any suggestion how to achieve running multiple simulations (sequentially) in the same gradle project?
EDIT: my currently ugly workaround (suggestions welcome to make it less ugly, but still workaround imo) is to modify the Gradle build file with:
task loadTests;
fileTree(dir: 'src/test').include("**/*Simulation.scala").each {target ->
ext {
filename = target.toString()
filename = filename.substring(filename.indexOf("scala") + "scala".length() + 1)
filename = filename.substring(0, filename.indexOf(".")).replaceAll("/", ".")
}
task("loadTest${filename}", type: GatlingTask, dependsOn: 'testClasses', description : "Load test ${filename}s") {
gatlingSimulation = filename
jvmOptions {
jvmArgs = [
"-Dlogback.configurationFile=${logbackGatlingConfig()}",
"-Denv=${System.getProperty('env', 'stg')}",
]
minHeapSize = "1024m"
maxHeapSize = "1024m"
}
}
loadTests.dependsOn("loadTest${filename}")
}
def logbackGatlingConfig() {
return sourceSets.test.resources.find { it.name == 'logback-gatling.xml' }
}
Basically, I create a GatlingTask for each *Simulation.scala file (naming convention) and then create a bulk loadTests task that depends on all.

Using gradle project variable in buildscript scope

There is a similar question here Access project extra properties in buildscript closure
but i found a "workaround" which does not look like the optimum
I have a multi gradle project - im declaring the repository in the main gradle file
using
subprojects {
repostiories {
maven {..}
}
}
now i also have to set these for the build script because im using a plugin !
so again buildscript { repositories ...
Now instead of pasting the URLs twice i wanted to use a property - as i figured project.ext properties are not set during the buildscript stage thus i put them
in my gradle.settings file
i couldnt set rootProject.ext.xx settings so i had to use
gradle.ext {
mavenURLs = [ companyURL1, companyURL2 ... etc]
}
Now i could use gradle.ext.mavenURLs in my build.gradle file
Is there a better way ?
Is there a way to set the buildscript and dependency repositories for all project in one block without repeating once for buildscript and once for the dependency ?
def repoClosure = { RepositoryHandler repoHandler ->
repoHandler.mavenLocal()
repoHandler.mavenCentral()
['http://mycompany/repo1', 'http://mycompany/repo2'].each { mavenURL ->
repoHandler.maven {
url mavenURL
credentials {
username 'foo'
password 'bar'
}
}
}
}
project.with {
allprojects {
repoClosure(buildscript.repositories)
repoClosure(repositories)
}
}
Simply create my-repositories.gradle file, with content like:
def repoClosure = {
maven {
url uri("${rootProject.rootDir}/offline-repository")
}
google()
mavenCentral()
['http://mycompany/repo1', 'http://mycompany/repo2'].each { mavenURL ->
maven {
url mavenURL
credentials {
username 'my-name'
password 'my-password'
}
}
}
}
project.with {
allprojects {
buildscript {
ext.myVariable = "Just an example!"
repositories(repoClosure)
}
repositories(repoClosure)
}
}
Then in your build.gradle apply it, like:
buildscript {
apply from: './my-repositories.gradle'
ext {
kotlin_version = '1.5.30'
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
// ...

(No such file or directory) how to make non existant file to be ignored by gradle

when i run the command 'gradle tasks' or anything for that fact, i got the following error:
Caused by: java.io.FileNotFoundException: /Users/maxit/workspace/Backbone/modules/contact-form/public/build/contact-src.js (No such file or directory)
Here is my gradle build file:
configurations {
sshAntTask
}
dependencies {
sshAntTask 'org.apache.ant:ant-jsch:1.7.1', 'jsch:jsch:0.1.29'
}
// Pull the plugin from Maven Central
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.eriwen:gradle-js-plugin:1.5.0'
}
}
// Invoke the plugin
apply plugin: 'js'
apply plugin:'base'
def appName = "some"
def version = "0.0.1"
def jsSrcDir = 'public/js'
javascript.source {
dev {
js {
srcDir jsSrcDir
include "*.js"
exclude "*.min.js"
}
}
prod {
js {
srcDir jsSrcDir
include "*.min.js"
}
}
}
task combineSrc(type: com.eriwen.gradle.js.tasks.CombineJsTask) {
source = ["${projectDir}/public/templates/templates.js","${projectDir}/public/js/models/contact_model.js", "${projectDir}/public/js/views/contact_form_view.js", "${projectDir}/public/js/app.js" ]
dest = file("${projectDir}/public/build/${appName}-src.js")
}
task appendJQuery(dependsOn: 'combineSrc') {
String backboneSrc = file(new File("${projectDir}/public/build/${appName}-src.js")).text
new File("${projectDir}/public/build/${appName}-jqueryWraped.js").withWriter{ out ->
out << "(function(\$){" + file("${projectDir}/public/build/${appName}-src.js").text + "})(jQuery); \n"
}
}
It appears, that gradle doesn't ignore a file that is none existant. The task 'combineSrc' hasn't been run, yet to create the file....and i am unable to run the task 'cobineSrc' to create the file in the first place. Its kind a dead end. what am i doing wrong and how to make this work? Thank you
The reason you're failing is, that all the stuff you currently doing during the configuration of the appendJQuery task should be done in the execution phase.
just refactor your appendJQuery task to do:
task appendJQuery(dependsOn: 'combineSrc') {
doLast{
String backboneSrc = file(new File("${projectDir}/public/build/${appName}-src.js")).text
new File("${projectDir}/public/build/${appName}-jqueryWraped.js").withWriter{ out ->
out << "(function(\$){" + file("${projectDir}/public/build/${appName}-src.js").text + "})(jQuery); \n"
}
}
}
hope that helps!
René

Resources