The projectDir is invisible from the task class in Gradle script - class

It is an example of a build.gradle set on an empty freshly created Gradle/Groovy project on IntellJ. I use projectDir here in two places: in task definition and in task class definition. IntelliJ shows me the first use as incorrect - cannot resolve symbol. And it sees the second use as a correct one.
group 'test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'groovy'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
task ProjectDirTest(type: ProjectDirTestClass){
println " -------------- $projectDir from task"
}
class ProjectDirTestClass extends DefaultTask {
#TaskAction
def greet() {
println " -------------- $projectDir from class"
}
}
configure(ProjectDirTest) {
group = 'ProjectDirTest'
description = 'ProjectDirTest'
}
But if I run the task, the first println works OK, with correct output:
12:55:41: Executing external task 'ProjectDirTest'...
-------------- C:\Users\543829657\testWorkspace from task
:ProjectDirTest FAILED
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\Users\543829657\testWorkspace\build.gradle' line: 28
* What went wrong:
Execution failed for task ':ProjectDirTest'.
> Could not get unknown property 'projectDir' for task ':ProjectDirTest' of type ProjectDirTestClass.
But, as you see, at the second println there is a problem - Gradle does not see the projectDir variable.
I am already accustomed to incorrect IntelliJ marking errors. But how can I make the task class to see the the projectDir variable in runtime?
In the real task class I also cannot use the exec() command - Gradle does not see it, too.

I have found a temporary solution, to pass the project variable into the class and call all project variables with it:
task ProjectDirTest(type: ProjectDirTestClass){
println " -------------- $projectDir from task"
projectLoc = project
}
class ProjectDirTestClass extends DefaultTask {
Project projectLoc
#TaskAction
def greet() {
println " -------------- ${projectLoc.projectDir} from class"
}
}
The negative side is that I have to pass the same project for every task using that task class. It is not a good style.

Related

Spring Rest Doc (Gradle) Snippets disappear upon build

Recently switch to Gradle from Maven.
Following this tutorial for continuous REST Doc build with Gradle. https://www.youtube.com/watch?v=k5ncCJBarRI&t=1490s
Snippets are generating just fine when running test. Its when I am trying to generate asciidoc where it seems like the /build directory gets recreated without the snippets. So my generated html always shows
Unresolved directive in index.adoc - include::{snippets}/home-json/curl-request.adoc[]
I am generating the asciidoc by the following command in the terminal
gradle asciidoctor -t
// Continuous build command
// Mentioned around #1:07:40 mark
// https://www.youtube.com/watch?v=k5ncCJBarRI&t=1490s
build.gradle
plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.asciidoctor.convert' version '1.5.8'
id 'java'
}
group = 'lab.restdocs'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'
repositories {
mavenCentral()
}
ext {
set('snippetsDir', file("build/generated-snippets"))
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'junit:junit:4.12'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
test {
outputs.dir snippetsDir
useJUnitPlatform()
}
asciidoctor {
inputs.dir snippetsDir
dependsOn test
}
bootJar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
MyTest
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class HelloControllerTest {
#Autowired
private MockMvc mockMvc;
#Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
#InjectMocks
private HelloController helloController;
#Mock
private HelloService helloService;
#Before
public void setUp() throws Exception {
// create a mock environment of helloController
mockMvc = MockMvcBuilders.standaloneSetup(helloController)
.apply(documentationConfiguration(this.restDocumentation))
.build();
}
#Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/hello/string"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString("hello there"))
)
.andDo(document("home-string"));
}
I also checked my build.gradle against https://spring.io/guides/gs/testing-restdocs/ and https://docs.spring.io/spring-restdocs/docs/2.0.5.RELEASE/reference/html5/#configuration-uris. I don't know what I am missing...
Thanks in advance.
Edited
Ran command gradle asciidoctor --console=plain
If it makes it easier I greated a Git repo
https://github.com/erich5168/edu.rest-doc
erichuang$ gradle asciidoctor --console=plain
> Task :compileJava
> Task :processResources
> Task :classes
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test
> Task :asciidoctor
asciidoctor: WARNING: api.adoc: line 3: include file not found: /Users/erichuang/Desktop/JE/00-Development/dev/lab/lab-rest-docs/lab.restdocs-gradlebuild/build/generated-snippets/home/curl-request.adoc
asciidoctor: WARNING: api.adoc: line 5: include file not found: /Users/erichuang/Desktop/JE/00-Development/dev/lab/lab-rest-docs/lab.restdocs-gradlebuild/build/generated-snippets/home/http-request.adoc
asciidoctor: WARNING: api.adoc: line 7: include file not found: /Users/erichuang/Desktop/JE/00-Development/dev/lab/lab-rest-docs/lab.restdocs-gradlebuild/build/generated-snippets/home/http-response.adoc
asciidoctor: WARNING: api.adoc: line 20: include file not found: /Users/erichuang/Desktop/JE/00-Development/dev/lab/lab-rest-docs/lab.restdocs-gradlebuild/build/generated-snippets/home-json/http-response.adoc
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 2s
5 actionable tasks: 5 executed
Apples-MBP:lab.restdocs-gradlebuild erichuang$
When run from the command line, you build isn't running any tests. The tests aren't being run as your tests are using JUnit 4 while the test task has been configured to use the JUnit Platform (JUnit 5):
test {
outputs.dir snippetsDir
useJUnitPlatform()
}
You can fix the problem either by updating your tests to use JUnit 5 or by removing useJUnitPlatform() from the test task's configuration so that it uses JUnit 4. The latter is the smaller change and leaves the test task looking like this:
test {
outputs.dir snippetsDir
}

How to call a scala method from build.gradle file

I have just started working on the scala and gradle. I want to know how we can call any scala method from the gradle build file. Can somebody please help me?
From comment: I want to run multiple files present in a directory. So in order to get all the files in the directory, I have written a method in scala. That method I am trying to call from build.gradle file
Gradle allows to specify dependencies of build script itself inside buildscript{ dependencies { ... } } (not to be confused with project dependencies inside ordinary dependencies { ... }).
For example here I added Shapeless dependency and used an HList in build.gradle
build.gradle
buildscript{
dependencies {
classpath group: 'com.chuusai', name: 'shapeless_2.13', version: '2.4.0-M1'
}
}
plugins {
id 'java'
id 'scala'
id 'application'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
// compile group: ...
}
application {
mainClassName = 'App'
}
import shapeless.*
task hello {
doLast {
HList l = new $colon$colon(1, new $colon$colon("a", new HNil$()))
println l
}
}
Terminal
$ ./gradlew hello
Output
> Task :hello
1 :: a :: HNil
BUILD SUCCESSFUL in 457ms
1 actionable task: 1 executed
So you can compile your Scala sources, package classes into jar, publish it locally and specify your local dependency in
buildscript{
dependencies {
classpath group: 'yourOrganization', name: 'yourArtifact', version: 'yourVersion'
}
}
and then call methods from your Scala code in build.gradle.

Gradle execute Groovy script in GroovyShell with Eclipse Luna

I am getting a ClassNotFoundException: org.apache.ivy.core.report.ResolveReport when executing a gradle task, which uses Grapes to resolve dependencies.
I am using Eclipse Luna 4.4.0 with a Gradle/Groovy Project having this build.gradle:
apply plugin: 'groovy'
apply plugin:'application'
mainClassName = "de.my.app.package.Main"
version = 0.5
repositories { mavenCentral() }
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.3'
compile group: 'org.apache.ivy', name:'ivy', version:'2.2.0'
compile 'commons-io:commons-io:2.4'
compile 'commons-codec:commons-codec:1.2'
}
task myTask << {
def groovyShell = new GroovyShell()
groovyShell.run(file('/src/scripts/groovy/de/my/app/package/scripts/SomeScript.groovy'))
}
classes.finalizedBy(myTask)
My Java Build Path inside Project->Properties looks like this:
This is SomeScript.groovy inside the Folder /src/scripts/groovy/de/my/app/package/scripts:
package de.my.app.package.scripts
#Grapes(
#Grab(group='org.eclipse.birt.runtime.3_7_1', module='org.apache.commons.codec', version='1.3.0')
)
#Grapes(
#Grab(group='commons-io', module='commons-io', version='2.4')
)
import org.apache.commons.codec.binary.Hex
println Hex.toString()
Weird thing is that executing SomeScript.groovy from cmd with groovy SomeScript.groovy does not give the error. So i am guessing it is some Eclipse config I have missed.
How can SomeScript.groovy be executed by the Gradle run from the build.gradle without causing a ClassNotFoundException: org.apache.ivy.core.report.ResolveReport?
I have found a solution for my problem. I needed this build.gradle file:
apply plugin: 'groovy'
apply plugin:'application'
mainClassName = "de.my.app.package.Main"
version = 0.5
repositories { mavenCentral() }
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.3'
compile group: 'org.apache.ivy', name:'ivy', version:'2.2.0'
compile 'commons-io:commons-io:2.4'
compile 'commons-codec:commons-codec:1.2'
}
task myTask (type: Exec) {
def groovyHome = System.getenv("GROOVY_HOME")
def someScriptPath= new String(project.projectDir.toString()).toString() + "\\src\\scripts\\groovy\\de\\my\\app\\package\\main\\SomeScript.groovy"
commandLine "${groovyHome}\\bin\\groovy.bat", someScriptPath
}
classes.finalizedBy(myTask)
So I abandoned the approach of using the class GroovyShell, because I could not configure the classPath for it correctly.
My Script executes now before every run. Problem is solved.

ScalaTest with Groovy in Jenkins

I'm trying to build a scala project with groovy and jenkins. The unit tests are working locally but not on jenkins.
build.gradle
apply plugin: 'idea'
apply plugin: 'scala'
repositories {
mavenCentral()
}
dependencies {
compile 'junit:junit:4.11',
'org.scala-lang:scala-library:2.11.1',
'com.github.nscala-time:nscala-time_2.10:1.0.0'
testCompile 'org.scalatest:scalatest_2.11:2.1.6',
'org.scalautils:scalautils_2.11:2.1.6',
'org.scala-lang:scala-library:2.11.1'
}
compileTestScala << {
classpath= classpath.asPath + ":" + compileScala.destinationDir
}
test << {
ant.taskdef(
name: 'scalatest',
classname: 'org.scalatest.tools.ScalaTestAntTask',
classpath: classpath.asPath
)
print(classpath.asPath)
ant.scalatest(
runpath: testClassesDir,
haltonfailure: 'true',
fork: 'false') {
reporter(type: 'stderr')
}
}
Log
:compileTestScala
[ant:taskdef] Could not load definitions from resource scala/tools/ant/antlib.xml. It could not be found.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileTestScala'.
Cause: Problem: failed to create task or type scalac
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':compileTestScala'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:71)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:48)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:34)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:41)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:42)
at org.gradle.api.internal.AbstractTask.execute(AbstractTask.java:237)
at org.gradle.execution.DefaultTaskGraphExecuter.executeTask(DefaultTaskGraphExecuter.java:167)
at org.gradle.execution.DefaultTaskGraphExecuter.doExecute(DefaultTaskGraphExecuter.java:160)
at org.gradle.execution.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:78)
at org.gradle.execution.TaskNameResolvingBuildExecuter.execute(TaskNameResolvingBuildExecuter.java:113)
at org.gradle.execution.DelegatingBuildExecuter.execute(DelegatingBuildExecuter.java:54)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:158)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:112)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:80)
at org.gradle.launcher.RunBuildAction.execute(RunBuildAction.java:41)
at org.gradle.launcher.RunBuildAction.execute(RunBuildAction.java:27)
at org.gradle.launcher.ExceptionReportingAction.execute(ExceptionReportingAction.java:32)
at org.gradle.launcher.ExceptionReportingAction.execute(ExceptionReportingAction.java:21)
at org.gradle.launcher.CommandLineActionFactory$WithLoggingAction.execute(CommandLineActionFactory.java:219)
at org.gradle.launcher.CommandLineActionFactory$WithLoggingAction.execute(CommandLineActionFactory.java:203)
at org.gradle.launcher.Main.execute(Main.java:55)
at org.gradle.launcher.Main.main(Main.java:40)
at org.gradle.launcher.ProcessBootstrap.runNoExit(ProcessBootstrap.java:46)
at org.gradle.launcher.ProcessBootstrap.run(ProcessBootstrap.java:28)
at org.gradle.launcher.GradleMain.main(GradleMain.java:24)
Caused by: : Problem: failed to create task or type scalac
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.
at org.apache.tools.ant.UnknownElement.getNotFoundException(UnknownElement.java:487)
at org.apache.tools.ant.UnknownElement.makeObject(UnknownElement.java:419)
at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163)
at org.gradle.api.internal.project.ant.BasicAntBuilder.nodeCompleted(BasicAntBuilder.java:71)
at org.gradle.api.internal.project.AntBuilderDelegate.nodeCompleted(DefaultIsolatedAntBuilder.groovy:137)
at org.gradle.api.internal.tasks.scala.AntScalaCompiler$_execute_closure1.doCall(AntScalaCompiler.groovy:56)
at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:61)
at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:31)
at org.gradle.util.ConfigureUtil$configure.call(Unknown Source)
at org.gradle.api.internal.project.DefaultIsolatedAntBuilder.execute(DefaultIsolatedAntBuilder.groovy:98)
at org.gradle.api.internal.project.IsolatedAntBuilder$execute.call(Unknown Source)
at org.gradle.api.internal.tasks.scala.AntScalaCompiler.execute(AntScalaCompiler.groovy:53)
at org.gradle.api.internal.tasks.scala.DefaultScalaJavaJointCompiler.execute(DefaultScalaJavaJointCompiler.java:75)
at org.gradle.api.internal.tasks.compile.IncrementalJavaSourceCompiler.execute(IncrementalJavaSourceCompiler.java:73)
at org.gradle.api.tasks.scala.ScalaCompile.compile(ScalaCompile.java:89)
at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:158)
at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:93)
at org.gradle.api.tasks.scala.ScalaCompile_Decorated.invokeMethod(Unknown Source)
at org.gradle.util.ReflectionUtil.invoke(ReflectionUtil.groovy:23)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$2.execute(AnnotationProcessingTaskFactory.java:129)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$2.execute(AnnotationProcessingTaskFactory.java:127)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:63)
... 28 more
The build server had an older version of gradle installed. Had to install the newest version by hand and then it worked

Can't run Scalatest with Gradle

task scalaTest(dependsOn: testClasses) << {
description = 'Runs Scalatest suite'
ant.taskdef(name: 'scalatest',
classname: 'org.scalatest.tools.ScalaTestAntTask',
classpath: sourceSets.test.runtimeClasspath.asPath
)
ant.scalatest(runpath: sourceSets.test.output.classesDir,
haltonfailure: 'true', fork: 'false') {
reporter(type: 'stdout')
}
}
I run gradle scalaTest and I get:
* What went wrong:
Execution failed for task ':scalaTest'.
> java.lang.NoClassDefFoundError: scala/reflect/ClassManifest$
I am using Scala 2.10.2 and Gradle 1.7
dependencies {
compile 'org.scala-lang:scala-library:2.10.2'
testCompile 'org.scalatest:scalatest:1.3'
testCompile 'org.scalamock:scalamock_2.10:3.0.1'
}
What's wrong??
I do not know how to solve this one, but I can offer you a workaround. Annotate your test classes with #RunWith(classOf[JUnitRunner]), like this:
import org.scalatest.junit.JUnitRunner
import org.junit.runner.RunWith
#RunWith(classOf[JUnitRunner])
class MyTest extends FunSpec{
}
and then, gradle test should work.
Edit:
My dependencies:
compile "org.scala-lang:scala-library:2.10.1"
testCompile "org.scalatest:scalatest_2.10:1.9.1"
You can put the following in your build.gradle:
task spec(dependsOn: ['testClasses'], type: JavaExec) {
main = 'org.scalatest.tools.Runner'
args = ['-R', 'build/classes/scala/test', '-o']
classpath = sourceSets.test.runtimeClasspath
}
Note: The path my be different depending on the gradle version as pointed out in the comments by #MikeRylander. Before gradle 4 it used to be 'build/classes/test'.
Then just run gradle spec to execute your tests.
I named the task spec because there already is a test task. I don't know if you can override the default test task.
You can look up the available options here.
This response may be a bit late. But for one using scala with gradle (5.x), the following works.
Add the following plugin to gradle.
plugins {
id "com.github.maiflai.scalatest" version "0.25"
}
To run the code
> gradle test
As a bonus the test results from the above plugin would also be reported better than the default report.
rarry is correct. And even better, you can annotate a base test class with #RunWith(classOf[JUnitRunner]) once to cause all of your ScalaTest tests to run with the JUnit runner (assuming they extend the base class), e.g.:
import org.junit.runner.RunWith
import org.scalatest._
import org.scalatest.junit.JUnitRunner
#RunWith(classOf[JUnitRunner])
abstract class UnitSpec extends FlatSpec with Matchers
As of Gradle 3.2.1, following root build.gradle runs both JUnit and ScalaTest code. This code is for multi-project build, enabled via settings.gradle, that's why subprojects used.
Plus, it's on purpose uses explicit Gradle API, to minimize Gradle DSL magic.
description = 'root project'
def enableScalaTest(Project project) {
Task scalaTest = project.task(
[
'dependsOn': 'testClasses',
'description': 'Runs ScalaTest tests in the project'
],
'scalaTest',
{
ext.inputDir = project.tasks.getByName('compileTestScala').destinationDir
inputs.dir(ext.inputDir)
}
)
scalaTest.doLast({
ant.taskdef(name: 'scalatest',
classname: 'org.scalatest.tools.ScalaTestAntTask',
classpath: project.sourceSets.test.runtimeClasspath.asPath)
ant.scalatest(runpath: ext.inputDir,
fork: 'false',
haltonfailure: 'true')
{ reporter(type: 'stdout') }
})
project.getTasks().getByName('build').dependsOn(scalaTest)
}
subprojects {
apply plugin: 'scala'
repositories {
mavenCentral()
}
dependencies {
compile 'org.scala-lang:scala-library:2.12.1'
testCompile 'junit:junit:4.12'
testCompile 'org.scalatest:scalatest_2.12:3.0.1'
}
enableScalaTest(delegate)
}