Gradle composite build with custom gradle plugin fails in IntelliJ: "Could not find method api() for arguments" - gradle

I have a Gradle composite build project which contains a custom Gradle plugin. This project builds fine when using Gradle CLI, but IntelliJ fails.
I tried a few different variations on the plugin version within the resolutionStrategy block: org.test:test-plugin:0.0.1 and test-plugin:test-plugin.gradle.plugin:0.0.1 as described here: https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_markers - both of those work from the CLI; changing to invalid values ("blah:blah") causes a failure.
I've made a sample Github project that contains the code to reproduce, here: https://github.com/mwmitchell/intellij-gradle-plugin-composite-build-bug along with instructions to reproduce and a workaround. The workaround is something that's not really feasible for me, as it requires repeating configuration code (dependencies, plugins etc.) and I have many, many projects that require the same/common configuration.
I would expect IntelliJ to load the project successfully, just like the CLI does. It seems like IntelliJ is loading the sub-project (:project-1:library-a) before the parent (:project-1), such that the java-library is not actually applied to the sub-project when it's evaluated.

Thanks for the sample project! Indeed, it is an issue in IntelliJ IDEA, see this ticket.

Gradle projects can have only one settings.gradle. You can include subproject "library-a" with include 'project-1:library-a' in the main settings.gradle.

Related

How to use custom gradle plugin without publishing it to maven/ivy repositories?

I have 2 gradle projects. One is my custom gradle plugin and the other one is project which uses this plugin.
I know I can build my custom plugin, publish it to some repository and use it in my other project but is there any way how can I set something like "dependency" for my plugin (in build.gradle of my other project) and use it without need of building/publishing it somewhere?
To get and idea what I am trying to accomplish, here is some code which hopefully demonstrates the idea:
buildScript {
dependencies {
compile project(":my-gradle-plugin")
}
}
apply "my-gradle-plugin"
You can do that if your plugin project can be moved inside buildSrc of the project that wants to include it. In that case, the plugin will be by default on the classpath of the project.
If that plugin is shared between multiple projects, you will need to produce the binary and then reference it. Note that a local repository can be used, it does not have to be a remote one. One advantage of using a local repository is that Gradle will not cache the resolved plugin and thus any update, even without a version change, will be picked up immediately.

Parent pom usage in build.gradle

I have a need to convert the maven project to gradle project. All is going fine, but there is one problem that I faced, in the current project we are using dependency management throw parent pom of maven and in gradle as long as I researched there is no possibility to do so. I was thinking to convert somehow parent pom to maven bom and use in build.gradle because I know that gradle can use maven boms.
Do anyone have better ideas how to accoplish that ?
Or may be someone also had this kind of problem, can suggest best ways to do it ?
Regards
You could use my gradle-maven-transform plugin to transform your pom.xmls into gradle scripts.
You can use the DependencyAggregator to find versions which are common across all projects and generate a root build.gradle containing the common versions.
Each project script can then reference a version variable from the root project instead of hard coding
You might choose to use nebula dependency recomnender plugin to manage common versions. The maven-transform plugin can generate scripts to support this style of declaration too
Whilst you are evaluating the gradle build you "apply" the generated gradle scripts in your gradle build. During this time both maven and gradle builds will work in parallel. Once your happy with the gradle build you copy paste the generated scripts into your build.gradle files and ditch maven for ever! Yay!

How to elegantly build selected parts of a project

I have a project where I ideally wanted to be able to write something like this:
gradle build
or
gradle build -Pparts=part1,part5
Where the first command builds the whole project with a core part and all other parts. The second command builds the core part and selectively part1 and part5.
What I ended up with was splitting it up into subprojects and configuring them in the root build.gradle like this:
https://gist.github.com/Homyk/2d1d50b4678203817eaf
I can now do
gradle pack
or
gradle pack -Pparts=part1,part5
Which is fine but there are two problems at least that I would like to have solved:
I have to write a made up command instead of gradle build, which I care about because it`s open source, and I should not have to explain that.
With subprojects in Eclipse at least it`s very cumbersome to get it to build from Eclipse and develop effectively even when running 'gradle eclipse'. I ended up importing each subproject as a project which is pretty awful.
If I would solve this problem again starting from scratch what would the most elegant solution be?
Considering what you describe I would definitely go for a multi project set-up, this solves problem one as there are default ways to call only certain subprojects. More about multi-project build can be found here and a more specific StackOverflow question about executing tasks of subprojects can be found here.
I do not recognize the issues you describe in problem two. The integration in Eclipse works just fine after I installed the Gradle Integration for Eclipse Eclipse plugin from Springsource (although I have some JUnit issues). After you installed the Eclipse plugin just do the following to import the projects:
Apply the eclipse plugin to your Gradle build files.
In Eclipse open the 'Import' dialog by opening. By clicking File -> Import...
Choose Gradle Project as import source (located under the 'Gradle' category).
The 'Import Gradle Project' dialog will pup-up. Select the folder the root project is located in as root folder. Click Build Model. This should display the root project and it's subprojects. Select which project you want to import (probably all). Specify your 'Import Options' (I select everything except of the 'Use hierarchical project names'-option). Optionally add the projects to a working set. Than click Finish. The project should have been correctly imported.

gradle resolve the dependencies if the artifact is not found then build the dependent and upload the artifact

During configuration cycle of gradle where it tries to resolve the dependencies is there a way where I can add custom task/plugin such as to build the dependent project(details of svn path of the dependent project is provide thru ext properties) if the artifact is not found.
Thank you.
There isn't currently a built-in feature for this. It may be possible to implement this yourself, but it won't be easy. To get started, have a look at https://github.com/pniederw/elastic-deps, which is a proof-of-concept to replace project dependencies with external dependencies if they aren't available locally.
PS: Configurations are resolved when their artifacts are first requested, which typically happens in the execution phase (not configuration phase).
I had a need for the same feature. Getting it to work with gradle was a cinch. The hard part was figuring out how Android Studio syncs the gradle files. Without a successful sync, the IDE will complain it can't find any dependencies. At any rate, I figured it out, here is my solution to make it work with gradle and Android Studio.
https://gist.github.com/vangorra/c1383c355ce8fe56adf8
It essentially boils down to defining the project in settings.gradle:
include 'library'
project(':library').projectDir = file('../Library/library')
Then you have to use a one-liner with options closure for your dependency:
compile ( project(':library').projectDir.exists() ? project(':library'): 'Library:library:unspecified#aar') {
transitive = true
}

Jenkins Sonar plugin throws duplicate source file error during analysis

I have set up Sonar with MySQL Database. My project is a multi module eclipse project, which means it has multiple plugins.
I have set up a Jenkins build with Maven to build this project and also installed Jenkins Sonar plugin to analyse the code with sonar.
All the configurations seem to be correct. However, when sonar tries to analyse this project after the build, it complains of duplicate source code and the build fails.
Each eclipse plugin has Activator.java class and Sonar complains that this is duplicate. I have excluded this class from analysis, but Sonar complains of classes in a particular plugin that is added as a dependency to lot other plugins.
Incomplete analysis of the code leads to other issues in Sonar for this project. like, even though the project is visible in the Sonar dashboard, it asks for authentication again on clicking the project, even though I am logged in as admin.
Any inputs on pointing me to the right direction would be very helpful.
Please let me know if any additional inputs are necessary to better understand my problem.
IMO, the best example you can follow is our Sonar Eclipse project: https://github.com/SonarSource/sonar-eclipse. This is also a multi-module Eclipse project.
In this example, you want to have a look at the parent module (https://github.com/SonarSource/sonar-eclipse/tree/master/org.sonar.ide.eclipse.parent) which goal is only to define the parent POM. Almost everything happens there.
I guess that you should find your way thanks to this.
I was able to fix this issue by removing the test tag in the parent pom.xml. This was somehow causing sonar to throw the duplicate source error. It was a tedious task to figure out the root cause and I had to reconstruct pom.xml from scratch, adding section by section.
Thanks to all for the help.

Resources