Generate multiple report types using CodeNarc in Gradle - gradle

I want to generate both HTML and console report in CodeNarc in Gradle.
My build.gradle:
apply plugin: 'codenarc'
...
codenarc {
toolVersion = '0.24.1'
configFile = file('config/codenarc/codenarc.groovy')
reportFormat = 'html'
}
This works fine, but I'd like also to have report displayed on console, as right now only link to HTML is displayed there. How can I request multiple report types?

Instead of running a second task to generate another report, you could make the following change to add another report format.
Then grab one of the files and write it to the console.
(You could just grab the HTML or XML report and write that to the console, but it may be hard to read without some formatting.)
Note: The reports closure will get you reports in different formats. The doLast will print the output of one of those reports to the console. If you do not need the console output, you can remove the doLast closure.
I would suggest changing your task like this:
task codenarcConsoleReport {
doLast {
println file("${codenarc.reportsDir}/main.txt").text
}
}
codenarcMain {
finalizedBy codenarcConsoleReport
reports {
text.enabled = true
html.enabled = true
xml {
enabled = true
destination = file("${codenarc.reportsDir}/customFileName.xml")
}
}
}
Note: This will not cause your task to run twice.

Best way I can think of is to create a separate task:
task codeNarcConsole(type: CodeNarc) {
// other config
reportFormat = 'console'
}
check.dependsOn('codeNarcConsole')
Not ideal, but workable. You could also post to Gradle Bugs about this to get it improved.

Related

Gradle exclude resources for one task but not for second

Is it possible to exclude resources for a task, but do not exclude them for a second task? Both are triggered from a third task like this:
task createBoth {
dependsOn = [createFirst, createSecond]
}
task createFirst {
sourceSets.main.resources.excludes = ['**/images']
}
task createSecond {
sourceSets.main.resources.excludes = []
}
I tried to exclude in doFirst{} method, but it did not work. If run as a single task then it works fine. Both results are the same version of my Java project. Except they have a different main class and one does not need all images. So I want to create both files in a single run. Is it even possible?
Attempt 2:
task createSystemcheckJar(type: OneJar) {
exclude('**/images/ads/images') // And some ohter combinations with stars
}
Same problem.

Set the properties in the configuration phase of a task in another task

I have spent the last few hours trying to find a solution for my requirement, without luck:
I have a task that has to run some logic in a certain path:
task run(type: MyPlugin) {
pathForPlugin = myPath //Defined as a property in another gradle file
}
I want to set the "pathForPlugin" property dynamically in another task because it has to be read from some configuration file.
task initPaths(type: PathFinder) {
configurationFile = 'C:\\myConfig.conf'
}
The myConfig.conf would look like this:
pathForPlugin = 'C:\\Correct\\Path'
The problem is that "initPaths" has to run before the configuration phase of "run".
I have tried several approaches for this (GradleBuild task, dependsOn, Using Properties in the Plugin for "Lazy Configuration") but every approach only takes effect in the Execution phase leading to the "pathForPlugin" always staying at its default value.
Is there some way i can realize this or should i look for another solution outside of the gradle build?
I found a solution for the problem:
Instead of defining a task "initPaths" i directly used the java class "Pathfinder" in the build script:
import mypackage.PathFinder;
new PathFinder(project).run()
You only have to make sure that this part is above the definition of the task where the properties are used.
I admit this is a bit of a "hacky" solution but it works fine for my requirement.
you can do like this:
ext {
myPath //use it as a global variable that you can set and get from different gradle tasks and files
}
task firstTask {
doLast {
ext.myPath = "your path"
}
}
task run(type: MyPlugin) {
doFirst { //executed on runtime not on task definition
pathForPlugin = ext.myPath //Defined as a property in another gradle file
}
}
//example 2 - create run task dynamic
task initPath {
doLast {
tasks.create(name: "run", type: MyPlugin) {
pathForPlugin = ext.myPath
}
}
}

Conditional logic in gradle build to only execute certain code when a specific task is running

So, I am using a plugin in my gradle build (the plugin is org.flywaydb.flyway but that is not really relevant). I want to validate the caller has passed in a runtime parameter when tasks from this plugin are executing but not when other tasks are executing.
I pass options to the flyway plugin based on a supplied parameter. I want an error to be returned when a flywayTask is being executed and no parameter is supplied. When a non-flyway task is being run, I do not want to validate if the parameter is supplied.
gradle -PmyParam=myValue flywayMigration
=> should run code and there should be no error
gradle flywayMigration
=> should run code and should produce error (as no parameter supplied)
gradle jar
=> should not run code and no error should be produced
I have been reading about gradle configuration and execution which is fine but I still can't find a way to only run the code when the flyway plugin is bveing executed OR specific flyway tasks are being executed.
This is my current code:
if(gradle.taskGraph.hasTask("flywayMigrate")) {
flyway {
def dbCode, dbUser, dbPassword, dbUrl
if (!project.hasProperty("db_env")) {
throw new GradleException("Expected db_env property to be supplied for migration task. Can be passed" +
" at command line e.g. [gradle -Pdb_env=ex1 flywayMigrate]")
} else {
// do stuff
}
user = balh
password = blah
url = blah
driver = 'oracle.jdbc.OracleDriver'
cleanDisabled = true
baselineOnMigrate = true
baselineVersion = '1.0.0'
}
}
To be clear, I only want this code:
if (!project.hasProperty("db_env")
to run for flyway tasks.
The code above throws this error:
Task information is not available, as this task execution graph has not been populated.
I've tried a few things here, any advice would be appreciated.
It's not really clear to me, what exactly do you want to do in case if this property is provided, but I think, you can do it without accesing task graph, just try to use doFirst Closure of the flywayMigrate task. Just something like this:
flywayMigrate.doFirst {
if(!project.hasProperty("db_env")) {
throw ...
} else {
//Do something
}
}
And leave your plugin configuration free of any additional logic.
As for exception, have you tried to wait until graph is ready? It's usualy done as follows:
gradle.taskGraph.whenReady {taskGraph ->
if(gradle.taskGraph.hasTask("flywayMigrate")) {
...
}
}
Update: to answer the question from the comments
if I can attach doFirst to multiple tasks?
Yes, you can use somthing like:
//declare task names
def names = ["taskA", "taskB", "taskC"]
tasks.findAll {it ->
//filter tasks with names
if (it.name in names)
return it
}.each { it ->
//add some extra logic to it's doFirst closure
it.doFirst {
println 'hello'
}
}
Just check, that all the tasks are exists before this configuration.

Specify Gradle Report Directory

I have several folders trying to seperate my tests up into unit, integration, 3rd party, db. This way I can have my tests seperated into chunks purposes, to make TDD easier/faster. Here is the task that I am trying to use.
task integrationTest(type: Test) {
testClassesDir = sourceSets.integration.output.classesDir
classpath = sourceSets.integration.runtimeClasspath
maxParallelForks 8
maxHeapSize = "4048m"
}
I know there is testReportDir, but it's deprecated. I want to be able to use the new method.
I have tried the following closures:
reports {
html = file("$buildDir/reports/intTests")
}
reports {
setDestination = file("$buildDir/reports/intTests")
}
reports {
destinationDir = file("$buildDir/reports/intTests")
}
destinationDir = file("$buildDir/reports/intTests")
I think you want
integrationTest.reports.html.destination = file("$buildDir/reports/intTests")
You may want to consult the api docs for TestTaskReports which shows that the html report is a DirectoryReport extending ConfigurableReport and that that provides the destination accessor referred to in the one liner above.
Maybe you can implement your own task of type TestReport similar to here. Note the feature is incubating though.

Moving built-in gradle tasks work to doLast/built-in tasks shourtcuts

I want to create a simple sync task that slightly change it behaviour depending on build type (e.g. debug/release) and I use boolean variable 'dummy' decrared in gradle.taskGraph.whenReady:
gradle.taskGraph.whenReady {taskGraph ->
dummy = false
if (taskGraph.hasTask(':dummybuild')) {
dummy = true
}
}
The problem is that task configured by the following way has configuration scope, i.e. before whenReady so it doesn't have access to the 'dummy' variable:
task copySkins(type: Sync) {
from skinsFrom
into skinsInto
rename skinsRename
exclude symbianExclude
if (!dummy) exclude dummyExclude
}
Right now I'm using this workaround
task copySkins {
inputs.dir skinsFrom
outputs.dir skinsInto
doLast {
task skins(type: Sync) {
from skinsFrom
into skinsInto
rename skinsRename
exclude symbianExclude
if (!dummy) exclude dummyExclude
}
skins.execute()
}
}
Is it possible to
detect/setup some build properties in some other place except whenReady
move sync task work to doLast
or at least have some shortcut for sync task (.execute() looks quite ugly)
1) whenReady event allows user to access fully-initialized task graph: all initialization is finished and tasks are ready to run. The only situation, when you need to detect/setup build properties here, is when you need to introspect current build setup.
If you do not need this information, you can place your initialization anywhere in your build script. At the very end, it is nothing but groovy script.
apply plugin: 'java'
def now = new Date()
compileJava.doFirst {
println "It is ${now}. We are starting to compile"
}
2) You can not move sync task work to doLast. But you can always add your actions to doFirst ;) I think, this should work:
task copySkins(type: Sync) {
from skinsFrom
into skinsInto
rename skinsRename
exclude symbianExclude
doFirst {
if (!dummy) exclude dummyExclude
}
}
3) With all said before, missing sync task shortcut should not be that painfull

Resources