I am using a gradle project to build a Jenkins shared library. I have a build.gradle with following content:
// Apply the groovy plugin to add support for groovy
apply plugin: 'groovy'
sourceSets {
main {
groovy {
srcDirs = ['src', 'vars']
}
}
test {
groovy {
srcDirs = ['test']
}
}
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'jcenter' for resolving your dependencies.
jcenter()
// You can declare any Maven/Ivy/file repository here.
maven {
url "https://repo.jenkins-ci.org/releases/"
}
}
// In this section you declare the dependencies for your production and test code
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.5.6'
compile 'org.apache.ivy:ivy:2.4.0'
testCompile 'junit:junit:4.12'
}
Inside my vars/ directory I have the following source code in it:
def call(Map params) {
2 pipeline {
3 agent none
4
5 stages {
6 stage('Build') {
7 agent { label 'maven'}
8 steps {
9 logError 'Hello world'
10 }
11 }
12 }
13 }
14 }
When I run ./gradlew build or ./gradlew compileGroovy the compilation goes through fine. It looks it is only doing syntax validation and does not care about linking the symbols such as pipeline or agent etc. Am I understanding it correctly?
Okay I think I figured it out. This is happening because groovyc (in this case gradlew compileGroovy is producing a byte code that does not translate high level language to its bytecode equivalent. Instead each line is replaced by a method dispatch. So line 2 in the code above will get replaced with
getMetaClass().invokeMethod(this, 'pipeline', closure)
This causes compile time check on pipeline symbol to be promoted to a runtime error.
Related
What do I want to do?
I want to tell CodeNarc which folders/directories it is supposed to scan/analyse.
I cant find anything about that on the official site (http://codenarc.sourceforge.net/) or on the gradle plugin documentation (https://docs.gradle.org/current/userguide/codenarc_plugin.html).
Results of my Research:
The only related thing I found was in the grails CodeNarc plugin documentation (https://grails.org/plugin/codenarc). There it says you can configure which source files are analysed by CodeNarc. But this seems to be the case only for the grails CodeNarc plugin not the gradle version.
The gradle CodeNarc documentation describes 3 tasks, one of them with the following:
codenarcSourceSet — CodeNarc
Runs CodeNarc against the given source set’s Java source files
Based on the description I thought I might be able to do something with that.
But when I look for all tasks my gradle Project got only "codenarcMain" and "codenarcTest".
My Set-up:
My gradle project got the following structure:
.git
-> ...
.gradle
-> ...
config
-> codenarc -> MyRuleset.groovy
gradle
-> ...
src
-> main
-> groovy -> ...
-> ressources
-> test
-> groovy -> ...
-> ressources
vars
-> ...
.gitignore
build.gradle
gradlew
gradlew.bat
ReadMe.txt
settings.gradle
My build.gradle looks like that:
plugins {
// Apply the groovy plugin to add support for Groovy
id 'groovy'
id 'codenarc'
}
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
maven { url "http://repo.jenkins-ci.org/releases/" }
maven { url "http://central.maven.org/maven2/" }
}
dependencies {
// https://mvnrepository.com/artifact/org.jenkins-ci.main/jenkins-core
compile group: 'org.jenkins-ci.main', name: 'jenkins-core', version: '2.179'
// https://mvnrepository.com/artifact/org.jenkins-ci.plugins/cloudbees-folder
compile 'org.jenkins-ci.plugins:cloudbees-folder:5.3#jar'
// https://mvnrepository.com/artifact/org.jenkins-ci.plugins.workflow/workflow-api
compile 'org.jenkins-ci.plugins.workflow:workflow-api:2.35#jar'
// https://mvnrepository.com/artifact/org.jenkins-ci.plugins.workflow/workflow-job
compile 'org.jenkins-ci.plugins.workflow:workflow-job:2.32#jar'
// https://mvnrepository.com/artifact/com.cloudbees/groovy-cps
compile group: 'com.cloudbees', name: 'groovy-cps', version: '1.28'
// https://mvnrepository.com/artifact/org.codenarc/CodeNarc
codenarc group: 'org.codenarc', name: 'CodeNarc', version: '1.1'
// Use the latest Groovy version for building this library
implementation 'org.codehaus.groovy:groovy-all:2.5.6'
// Use the awesome Spock testing and specification framework
testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
}
codenarc {
configFile = file("${project.projectDir}/config/codenarc/MyRuleset.groovy")
reportFormat = 'html'
reportsDir = file("$buildDir/reports/StaticCodeAnalysis")
maxPriority1Violations = 0
maxPriority2Violations = 0
maxPriority3Violations = 0
}
Specific goal:
I basically want CodeNarc to also scan scripts inside the "vars" folder/directory.
But it seems to do that only inside the src/main/groovy and src/test/groovy.
I also don't know exactly what the default paths are because I didn't find it in the documentation.
Seems like all you have to do is add the following to your gradle.build
sourceSets {
main {
groovy {
srcDirs = ['src/main', 'vars']
}
}
}
This way CodeNarc scans everything inside the src/main folder and everything inside the vars folder. (https://discuss.gradle.org/t/gradle-codenarc-plugin-how-to-change-target-folder-for-the-scan/32102/2)
[edit]
It is even possible to define your own codeNarc task:
sourceSets {
main {
groovy {
srcDirs = ['src']
}
resources {
srcDirs = []
}
}
test {
groovy {
srcDirs = ['test']
}
resources {
srcDirs = []
}
}
vars {
compileClasspath += main.compileClasspath
compileClasspath += main.output
groovy {
srcDirs = ['vars']
}
resources {
srcDirs = []
}
}
}
codenarc {
toolVersion = '1.3'
configFile = file("${project.projectDir}/config/codenarc/ruleset.groovy")
sourceSets = [sourceSets.main, sourceSets.test, sourceSets.vars]
reportsDir = file("$buildDir/reports/StaticCodeAnalysis")
}
codenarcMain {
configFile = file("${project.projectDir}/config/codenarc/MainRuleset.groovy")
}
codenarcTest {
configFile = file("${project.projectDir}/config/codenarc/TestRuleset.groovy")
}
codenarcVars {
configFile = file("${project.projectDir}/config/codenarc/VarsRuleset.groovy")
}
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.
I'm fairly new to Groovy and I'm trying to wrap my head around Gradle. If I import the org.jvnet.hudson.plugins through Grapes it works perfectly and the dependency is resolved. But if I try to retrieve the dependency using Gradle the dependency is not resolved.
The package org.eclipse.hudson:hudson-core:3.2.1 works with both Gradle and Grape.
A dependency that is not resolved using Gradle
compile 'org.jvnet.hudson.plugins:checkstyle:3.42'
A dependency which is resolved using Grape
#Grab('org.jvnet.hudson.plugins:checkstyle:3.42')
A dependency which is resolved using Gradle
compile 'org.eclipse.hudson:hudson-core:3.2.1'
Error during Gradle build
line 3, column 1.
import hudson.plugins.checkstyle.CheckStyleResultAction;
^
The build.gradle
apply plugin: 'groovy'
repositories {
mavenCentral()
maven {
url "http://repo.jenkins-ci.org/releases/"
}
}
configurations {
ivy
}
sourceSets {
main {
groovy {
srcDirs = ['src/']
}
}
test {
groovy {
srcDirs = ['test/']
}
}
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.11'
compile "org.apache.ivy:ivy:2.4.0"
ivy "org.apache.ivy:ivy:2.3.0"
// Works
compile 'org.eclipse.hudson:hudson-core:3.2.1'
// Does not work
compile 'org.jvnet.hudson.plugins:checkstyle:3.42'
}
tasks.withType(GroovyCompile) {
groovyClasspath += configurations.ivy
}
You're probably not actually downloading the jar you think you are. Looks like the default artifact that comes back from the org.jvnet.hudson.plugins:checkstyle:3.42 dependency is actually a file named checkstyle-3.42.hpi.
To get the jar which contains the classes instead, use:
compile group: 'org.jvnet.hudson.plugins', name: 'checkstyle', version:'3.42', ext: 'jar'
Then that class will be found on your classpath (and you'll be on to locating the next missing dependency).
1.My project has two main class i want to build jar for each main class using gradle. my source has 2 files ValidationRule.java
SupportValidator.java both the file have one main class each i want to
build the jar for each main class
i can achieve the same from eclipse working fine
2.I want to load the source file for my project from 2 different folder,some part is there in one folder and remaining is
there in
another folder i.e like
project/src snd another folder outside the project(../../../SharedClass)
my script as follows
apply plugin: 'eclipse'
apply plugin: 'java'
sourceCompatibility = 1.6
archivesBaseName = 'Process_XY'
configurations {
configurations.compile.transitive = false
}
dependencies {
compile fileTree(dir:'/trunk/Solutions/project/Source/Binaries/CommonFunctions/build/libs', include: '*.jar')
compile fileTree(dir:'/trunk/Solutions/project/lib/GeoTools/geotools-2.7.4-bin/geotools-2.7.4', include: '*.jar')
compile "org.apache.hadoop:hadoop-core:1.0.3"
compile "commons-collections:commons-collections:3.2.1"
compile "commons-configuration:commons-configuration:1.6"
compile "commons-discovery:commons-discovery:0.2"
compile "commons-lang:commons-lang:2.4"
compile "commons-logging:commons-logging:1.1.1"
compile "commons-logging:commons-logging:1.0.4"
compile "log4j:log4j:1.2.16"
compile "com.vividsolutions:jts:1.8"
compile "commons-net:commons-net:1.4.1"
compile "org.apache.hadoop:hadoop-core:1.0.3"
compile "commons-httpclient:commons-httpclient:3.0.1"
compile "org.mortbay.jetty:servlet-api:2.5-20081211"
compile "org.apache.hbase:hbase:0.94.0"
compile "org.apache.zookeeper:zookeeper:3.4.3"
}
repositories {
mavenCentral()
maven { url "https://repository.cloudera.com/artifactory/cloudera-repos/" }
maven { url "http://repo.springsource.org/libs-release" }
maven { url "http://repo.springsource.org/libs-milestone" }
maven { url "http://repo.springsource.org/libs-snapshot" }
maven { url "http://www.datanucleus.org/downloads/maven2/" }
maven { url "http://oss.sonatype.org/content/repositories/snapshots" }
maven { url "http://people.apache.org/~rawson/repo" }
}
jar {
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
manifest.attributes("Main-Class":"org.project.seismic.Process_XY")
}
sourceSets {
main {
java {
source = ['src/org', '../../../SharedClass/org']
}
}
}
above in sourceSets method i tried to load source from 2 folder but it
didnt worked
Thanks in advance..!!
How to achieve using gradle.
Ok, first of all, the source on a SourceDirectorySet takes another SourceDirectorySet. The srcDirs method however takes paths. Change that block to the following:
sourceSets {
main {
java {
srcDirs ['src/org', '../../../SharedClass/org']
}
}
}
And you can easily add a second jar task as follows:
task secondJar(type: Jar) {
name = other-main-jar
from ...
manifest.attributes(...)
}
assemble.dependsOn(secondJar)
This will register a new Jar task called secondJar and makes sure that when the project is assembled, this jar is also created.
I'm new to Gradle and it still seems a little magic to me.
In my project we do not use the default sourceDirs because we separate the different kinds of tests:
configure(subprojects) {
sourceSets {
test {
java.srcDir('src/test/unit/java')
resources.srcDir('src/test/unit/resources')
}
integrationTest {
java.srcDir('src/test/integration/java')
resources.srcDir('src/test/integration/resources')
}
concurrencyTest {
java.srcDir('src/test/concurrency/java')
resources.srcDir('src/test/concurrency/resources')
}
componentTest {
java.srcDir('src/test/component/java')
resources.srcDir('src/test/component/resources')
}
}
}
I'm trying to configure a scala test source directory. My attempt:
apply plugin: 'scala'
configure(subprojects) {
sourceSets {
test {
java.srcDir('src/test/unit/java')
scala.srcDir('src/test/unit/scala')
resources.srcDir('src/test/unit/resources')
}
...
The result:
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\projects\...\build.gradle' line: 109
# note, this is the line "sourceSets {"
* What went wrong:
A problem occurred evaluating root project 'X'.
> Could not find method sourceSets() for arguments [build_5ft63n6d7svimaibmkfq56rbrk$_run_closure4_closure18#573ed6c3] on root project 'X'.
I've tried a few other variants but cannot get it to work. Can someone help please?
The sourceSets extension is added by language plugins like scala, but you didn't apply the scala plugin to the subprojects. Hence the error.
PS: Instead of configure(subprojects) { ... }, you can just use subprojects { ... }.