How to generate source files and compile them with gradle - groovy

I have a gradle build script similar to:
apply plugin: 'war'
task genSources << {
// here I generate some java files
}
// making sure that source files are generated
// before compilation
compileJava.dependsOn(genSources)
How can I make the files generated in genSources compile along with files in src/main/java during compileJava?

You may try adding the path to the generated sources like this:
sourceSets {
main {
java {
srcDir '<path to generatedJava>'
}
}
}

Related

Create a Groovy executable jar with Spock test set as to be executed

I want to create jar with two groovy files, AppLogic.groovy which consists of two few groovy classes and another file, AppSpec that has Spock test suite and I would like to have this Spock class executed (set as executable). How can I create such jar with all dependencies? I found sth similar for jUnit here: how to export (JUnit) test suite as executable jar but could not adapt it for my needs.
I use gradle for build, here is my build.gradle file:
group 'someGroup'
version '1.0'
apply plugin: 'groovy'
apply plugin: 'java'
apply plugin:'application'
sourceCompatibility = 1.7
repositories {
//some repos here
maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
//some dependencies here
}
I was browsing around and found SpockRuntime, but I do not know if and how I can use it to achive my goal.
And the winner is:
static void main(String[] args) {
EmbeddedSpecRunner embeddedSpecRunner = new EmbeddedSpecRunner()
embeddedSpecRunner.runClass(MySpec)
}
I do not advise using the EmbeddedSpecRunner from spock implementation as described in accepted answer.
This is what I found to work reliably with gradle 4.9. The basic approach is to use:
The gradle application plugin to create a single tarfile with all testRuntimeClasspath dependencies and shell scripts to run the spock tests
The gradle maven-publish plugin to publish the tar file as an artifact to your maven repo (in my case nexus)
The build.gradle file looks like this:
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'maven-publish'
apply plugin: 'application'
mainClassName = 'org.junit.runner.JUnitCore' // The junit 4 test runner class
applicationName = 'run-tests-cli' // Feel free to change
repositories {
...
}
dependencies {
...
testImplementation "org.codehaus.groovy:groovy-all:${groovyVersion}"
testImplementation "org.spockframework:spock-core:${spockVersion}"
}
// Package compiled spock / junit tests to <artifact>-test-<version>.jar
task testJar(type: Jar) {
classifier = 'tests'
from sourceSets.test.output.classesDirs
}
// Copy all testRuntimeClasspath dependencies to libs folder
task copyToLibs(type: Copy) {
from configurations.testRuntimeClasspath
into "$buildDir/libs"
}
// Make sure test jar is copied
copyToLibs.dependsOn('testJar')
// Make sure platform-specific shell scripts are created after copyToLibs
startScripts.dependsOn(copyToLibs)
// Configure what goes into the tar / zip distribution file created by gradle distribution plugin assembleDist task
distributions {
main {
contents {
// Include test jar
from(testJar) {
into "lib"
}
// Include all dependencies from testRuntimeClasspath
from(copyToLibs) {
into "lib"
}
}
}
}
startScripts {
// Ensure ethat all testRuntimeClasspath dependencies are in classpath used by shell scripts
classpath = project.tasks['testJar'].outputs.files + project.configurations.testRuntimeClasspath
}
publishing {
repositories {
maven {
def releasesRepoUrl = "https://nexus.yourcompany.com/repository/maven-releases/"
def snapshotsRepoUrl = "https://nexus.yourcompany.com/repository/maven-snapshots/"
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username = rootProject.getProperty('NEXUS_USERNAME')
password = rootProject.getProperty('NEXUS_PASSWORD')
}
}
}
publications {
maven(MavenPublication) {
groupId = 'com.yourgroupId'
version = "${rootProject.getVersion()}"
}
TestJar(MavenPublication) {
artifact(testJar)
}
RunTestsCliTar(MavenPublication) {
artifact(distTar)
artifactId "${applicationName}"
}
}
}
Now you can do the following:
To build the project (including the tar file) without running test task: gradle -x test clean build
To publish artifacts produced by project (including tar file to maven repo - in my case nexus): gradlew -x test publish. Note you will need to provide credentials to upload artifacts to repo. It is good practice to define them (NEXUS_USERNAME, NEXUS_PASSWORD in my example) in ~/.gradle/gradle.properties or specify them via -P options on the gradle command line.

Trying to make an Android Studio Application with Adobe Creative SDK Image Editing, cannot get libraries compiled in gradle

I've been trying to properly import this library to begin writing an image editing component for my application. I currently have the downloaded 'creativesdk-repo' folder in the root directory, and have followed instructions according to this tutorial:
https://creativesdk.adobe.com/docs/android/#/articles/gettingstarted/index.html.
And this tutorial as well:
https://creativesdk.adobe.com/docs/android/#/articles/imageediting/index.html
There are no problems building when I simply use the basic authorization library, but my application needs photo editing capability. My foremost problem (among many) lies within the build.gradle file of the application (not the encompassing project build.gradle file).
Here is the code in my build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.0"
defaultConfig {
applicationId "com.example"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.adobe.creativesdk.foundation:auth:0.3.94'
compile 'com.adobe.creativesdk.image:4.0.0'
}
The very last line causes an error message to appear:
Error:Failed to resolve: com.adobe.creativesdk.image:4.0.0:
Open File
I believe these messages mean that the image editing portion of the Adobe Creative SDK libraries are not being recognized. I have even tested this with example projects from Adobe and it runs into the same problem. What can I do to fix this and start writing this portion of my application?
You need download creative-sdk repo from download links into your project folder. In the project gradle define creative-sdk repo url like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenCentral()
jcenter()
maven{
url "${project.rootDir}/creativesdk-repo" //ADD THE CORRECT LOCATION OF THE CREATIVESDK LIBRARY FILES
}
}
}
In your app build.gradle define this:
compile 'com.adobe.creativesdk.foundation:auth:0.3.94'
compile 'com.adobe.creativesdk:image:4.0.0'
You should extend your Application class and implement this, something like this:
public class ExampleApplication extends MultiDexApplication implements IAdobeAuthClientCredentials , IAviaryClientCredentials {
private static final String CREATIVE_SDK_SAMPLE_CLIENT_ID = "62bbd145c3f54ee39151823358c83e28";
private static final String CREATIVE_SDK_SAMPLE_CLIENT_SECRET = "2522a432-dfc8-40c4-94fe-646e10223562";
#Override
public void onCreate() {
super.onCreate();
AdobeCSDKFoundation.initializeCSDKFoundation(getApplicationContext());
}
#Override
public String getClientID() {
return CREATIVE_SDK_SAMPLE_CLIENT_ID;
}
#Override
public String getClientSecret() {
return CREATIVE_SDK_SAMPLE_CLIENT_SECRET;
}
#Override
public String getBillingKey() {
return "";
}
}
In your AndroidManifest.xml inside Application tag put this:
<provider
android:name="com.aviary.android.feather.sdk.internal.cds.AviaryCdsProvider"
android:authorities="com.package.AviaryCdsProvider"
android:exported="false"
android:process=":aviary_cds" />
With this configuration you can call Aviary Sdk Activity with this:
Intent newIntent = new AviaryIntent.Builder(this);
//config values
startActivity(newIntent);
I configure SDK like this, and its working. Sorry for the delay.
UPDATE 10/10/2016:
Thanks to Ash Ryan:
Trying to make an Android Studio Application with Adobe Creative SDK Image Editing, cannot get libraries compiled in gradle
Use this:
//noinspection SpellCheckingInspection
repositories {
// ...
// For Adobe Creative SDK
maven { url 'https://repo.adobe.com/nexus/content/repositories/releases/' }
}
Source: https://creativesdk.adobe.com/docs/android/#/articles/gettingstarted/index.html
Please make sure under global project repo. If not gradle not able to find the path.
allprojects {
repositories {
compile 'com.adobe.creativesdk.foundation:auth:0.3.94'
compile 'com.adobe.creativesdk:image:4.0.0'
}
I think your error is here. Change:
complie 'com.adobe.creativesdk.image:4.0.0'
for this:
compile 'com.adobe.creativesdk.image:4.0.0'
It`s a simple sintax error.
UPDATE 10/10/2016:
Thanks to Ash Ryan:
Trying to make an Android Studio Application with Adobe Creative SDK Image Editing, cannot get libraries compiled in gradle
just use latest lib dependency in Module:app build.gradle file and update your android sdk and android studio
compile 'com.adobe.creativesdk:image:4.6.3'

Fixing Gradle Artifactory plugin publishing issue

I have a multi-project build that I am building with Gradle:
myapp/
myapp-client/
myapp-shared/
myapp-server/
build.gradle
settings.gradle
Where settings.gradle looks like:
include ':myapp-shared'
include ':myapp-client'
include ':myapp-server'
I have successfully got Gradle to compile my Groovy source code, run unit tests, generate GroovyDocs, and package both binary and source JARs for all 3 subprojects. The build invocation for which is: gradle clean build groovydoc sourcesJar -Pversion=<whatever version I specify>.
I am now attempting to add the Gradle-Artifactory plugin such that:
All 3 subprojects get POMs generated for them; and
All 3 subproject binary JARs, POMs and source JARs get published to my locally-running Artifactory; and
The artifactoryPublish task executes whenever gradle build is invoked
Here's my best attempt (my complete build.gradle):
allprojects {
buildscript {
repositories {
maven {
url 'http://localhost:8081/artifactory/plugins-release'
credentials {
username = "admin"
password = "password"
}
name = "maven-main-cache"
}
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
}
}
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: "com.jfrog.artifactory"
version="0.0.1"
group = "mygroup"
repositories {
mavenCentral()
add buildscript.repositories.getByName("maven-main-cache")
maven {
url "http://localhost:8081/artifactory/mydev-snapshots"
}
}
artifactory {
contextUrl = "http://localhost:8081/artifactory"
publish {
repository {
repoKey = 'mydev-snapshots'
username = "admin"
password = "password"
maven = true
}
defaults {
publications ('mavenJava')
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
rootProject {
artifactoryPublish.skip=true
}
subprojects {
apply plugin: 'groovy'
apply plugin: 'eclipse'
sourceCompatibility = '1.7'
targetCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
repositories {
mavenLocal()
mavenCentral()
maven {
url "https://repository.apache.org/content/repositories/snapshots"
}
maven {
url "http://localhost:8081/artifactory/mydev-snapshots"
}
maven {
url "https://code.google.com/p/guava-libraries/"
}
}
dependencies {
compile (
'org.codehaus.groovy:groovy-all:2.3.7'
)
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
build(dependsOn: 'artifactoryPublish')
}
When I run gradle clean build groovydoc sourcesJar -Pversion=0.1.1, I get the following command line exception:
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\Users\myuser\sandbox\eclipse\workspace\myapp\build.gradle' line: 14
* What went wrong:
A problem occurred evaluating root project 'myapp'.
> You can't change a configuration which is not in unresolved state!
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 2.589 secs
My question: what is going on here, and what do I need to do (specifically) to fix it and get the Artifactory plugin publishing?
Bonus question: I'm specifying version number in 2 places (the build invocation as well as inside the build.gradle file. I want to specify version number only via the build invocation. How do I configure artifactoryPublish (or rather, the Gradle-Artifactory plugin) to accept the version I specify from the command-line?
Number of issues here:
buildscript should be top-level block, not inside allprojects
When using Artifactory, you don't need to specify any other repositories except of Artifactory (don't need mavenCentral())
If you want to use artifactoryPublish you need to configure the Artifactory plugin. Here are the docs and here are two fully working examples of multi-module Gradle projects: 1 and 2. Some highlights:
You need to apply maven or maven-publish plugin.
You need to add the produced artifacts to configuration or publication accordingly.
You need to configure the plugin with Artifactory instance you are working with, provide resolution and deployment repository names, credentials (usually for deployment only) and specify which configuration or publication you want to publish.

Custom Task/Plugin in gradle

I'm trying to create a custom Task/Plugin (both refuse to work) to use in my gradle build script.
I'm using the groovy plugin and want to declare the Tasks/Plugins in a separate files and not inside my build.gradle.
My project tree is the following:
/project
.
|-gradle
|-src
|---main
|-----groovy
|-----java
|-----resources
|---test
|-----groovy
|-----java
|-----resources
|-build.gradle
What I tried to do, is create my Task/Plugin classes inside src/main/groovy and then use them in my build.gradle.
Let me give a small example.
src/main/groovy/mypackage/TestTask.groovy:
package org.gradle.mypackage
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
public class TestTask extends DefaultTask {
#TaskAction
def doAction() {
}
}
build.gradle
plugins {
id 'groovy'
}
sourceCompatibility = 1.7
repositories {
mavenCentral()
}
dependencies {
compile(
localGroovy(),
gradleApi()
)
testCompile(
[ group: 'junit', name: 'junit', version: '4.11' ]
)
}
task testTask(type: TestTask)
When I try to do anything using my gradle.build (clean, build, etc), I get the following error:
Error:(116, 0) Could not find property 'TestTask' on root project 'project'.
What am I doing wrong? I tried to import the Task in build.gradle using import mypackage.TestTask but that didn't work either.
It looks to me like the groovy files do not compile at all while from what I read in the docs gradle should take care of compiling and adding them in the classpath.
Here you go: "in-stackoverflow" solution.
In your project create folder buildSrc/src/main
Don't forget to create build.gradle in buildSrc/
apply plugin: 'groovy'
dependencies {
compile gradleApi()
compile localGroovy()
}
Now in the main folder create package with your task, for example: pl.myAwesomeCompany.gradle.tasks
package pl.myAwesomeCompany.gradle.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
class ExampleTask extends DefaultTask {
#TaskAction
void execute(IncrementalTaskInputs inputs) {
println inputs.incremental ? "CHANGED inputs considered out of date"
: "ALL inputs considered out of date"
}
}
Voila! Now in your project you can use your plugin:
import package pl.myAwesomeCompany.gradle.tasks.ExampleTask
task incremental(type:ExampleTask)
This is not how it works. If you need to provide custom plugins and tasks organized in packages , put the whole code under buildSrc directory. Under $GRADLE_HOME/samples/multiProjectBuildSrc You can find excellent example how it should be done.
$GRADLE_HOME - gradle installation directory.

How to use uploadConfigurationName and buildConfigurationName

In gradle documentation we can read:
For each configuration in your project, Gradle provides the tasks uploadConfigurationName and buildConfigurationName [18].
As I understand I can create build which looks like this (without any plugin because I don't want to use plugins in this project):
configurations {
productSrc
}
// create zip file which will be published
buildProductSrc(type: Copy) << {
// do the job
}
// publish zip which were build by buildProductSrc
uploadProductSrc {
repositories {
ivy {
url "http://ivy.repo/repo"
}
}
}
So if I run gradle buildProductSrc uploadProductSrc it will build zip and piblish it on ivy repository. Do I understand it correctly becouse it doesn't work?
[UPDATE]
According to Peter Niederwieser answer this is a working version of build:
apply plugin: 'base'
configurations {
productSrc
}
// create zip file which will be published
buildProductSrc << { // unable to create specific task, for example 'type: Copy'
// do the job
}
// publish zip which were build by buildProductSrc
uploadProductSrc {
repositories {
ivy {
url "http://ivy.repo/repo"
}
}
}
To get uploadConfigurationName and buildConfigurationName tasks, you'll have to apply the base plugin, or a plugin that in turn applies the base plugin (java, groovy, etc.). Alternatively, you can declare and configure such tasks yourself (but it takes more effort).

Resources