i have two packages "../java/abc"(.java) and "../java/xyz"(.kt)
i need to exclude abc package content in dokka html document
basically i could see both the package are documented in HTML by dokka. after performing
'./gradlew dokkaHtml'
can anybody give me a solution where i can customize/limit the documentation only for 1 package?
i have plugin and dependency in project level build.gradel file
dependencies {
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.6.21"
}
plugins {
id 'org.jetbrains.dokka' version '1.6.21' apply false
}
my app.gredel file look like below
apply plugin: 'kotlin-parcelize'
apply plugin: 'org.jetbrains.dokka'
tasks.dokkaHtml.configure {
dokkaSourceSets {
configureEach {
perPackageOption {
matchingRegex.set("abc")
suppress.set(true)
}
}
}
}
and I have also tried the below syntax
tasks.dokkaHtml.configure {
dokkaSourceSets {
configureEach {
perPackageOption {
prefix = "abc"
suppress = true
}
}
}
}
Expectation: need to customize the documentation for only 1 package.
Related
I am trying to use Gradle Source Sets to configure different files for different environments, which is inspired by Gradles integration testing setup documentation.
My goal is to have both fake and prod source sets use interfaces defined in main and provide their own implementations. This is similar if not exactly what you can accomplish with the Android Gradle Plugin's Product Flavors.
For example, here is my build.gradle.kts file:
...
sourceSets {
create("prod") {
compileClasspath += sourceSets.main.get().output
runtimeClasspath += sourceSets.main.get().output
java.srcDirs("src/main/kotlin", "src/prod/kotlin")
}
create("fake") {
compileClasspath += sourceSets.main.get().output
runtimeClasspath += sourceSets.main.get().output
java.srcDirs("src/main/kotlin", "src/fake/kotlin")
}
}
val fakeImplementation by configurations.getting {
extendsFrom(configurations.implementation.get())
}
val prodImplementation by configurations.getting {
extendsFrom(configurations.implementation.get())
}
configurations["fakeRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())
configurations["prodRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())
val prodTest = task<Test>("prodTest") {
description = "Runs prod tests."
group = "verification"
testClassesDirs = sourceSets["prod"].output.classesDirs
classpath = sourceSets["prod"].runtimeClasspath
shouldRunAfter("test")
}
val fakeTest = task<Test>("fakeTest") {
description = "Runs fake tests."
group = "verification"
testClassesDirs = sourceSets["fake"].output.classesDirs
classpath = sourceSets["fake"].runtimeClasspath
shouldRunAfter("test")
}
tasks.check { dependsOn(prodTest) }
tasks.check { dependsOn(fakeTest) }
...
compileFakeKotlin doesn't recognize files in the fake source set, particularly on the kaptKotlin task which is defined like so in my dependencies block:
dependencies {
// Dagger
implementation("com.google.dagger:dagger:2.41")
kapt("com.google.dagger:dagger-compiler:2.41")
"kaptProd"("com.google.dagger:dagger-compiler:2.41")
"kaptFake"("com.google.dagger:dagger-compiler:2.41")
}
And here is the error:
> Task :server:compileKotlinCheckIncrementalCompilationAnvil UP-TO-DATE
> Task :server:kaptGenerateStubsKotlin UP-TO-DATE
> Task :server:processResources UP-TO-DATE
> Task :server:compileFakeKotlinCheckIncrementalCompilationAnvil UP-TO-DATE
> Task :server:kaptKotlin FAILED
...[Dagger/MissingBinding] my.package.name.RecipeController cannot be provided without an #Provides-annotated method.
public abstract interface AppComponent { ...
When I put the binding class(FakeRecipeController.kt) in the main source set, it works perfectly. But when it's in src/fake/kotlin, I get this error which leads me to believe the code in that source set isn't being used and I'm unsure how to proceed from here. Thank you.
I'm pretty (very) new to Gradle and I am evaluating the potential benefits of switching from SBT to Gradle in a Scala project at my current employer. As such I'm not looking to convert an entire build to Gradle right away but it seems it should be possible to dynamically base the Gradle build (atm, primarily compiler flags and dependencies with global versions). This way I don't unnecessarily increase the cognitive load on my colleagues but at the same time I don't run the risk of my build lagging behind or conflicting with the "canonical" configuration in the pom-files.
This is my current build.gradle (so far I have only started to tackle dependencies):
def dependencyVersions = [:]
new XmlSlurper().parse('pom.xml').dependencyManagement.dependencies.dependency.each {
dependencyVersions["${it.groupId}:${it.artifactId}"] = it.version.text()
}
allprojects {
group = 'my.org'
version = 'latest-SNAPSHOT'
}
subprojects {
apply plugin: 'java'
apply plugin: 'scala'
repositories {
mavenLocal()
maven {
url = uri('https://repo.maven.apache.org/maven2')
}
}
dependencies {
implementation 'org.scala-lang:scala-library:2.13.3'
// ... Global deps ...
new XmlSlurper().parse("$projectDir/pom.xml").dependencies.dependency.each {
if(it.groupId.text() == 'my.org') {
add('implementation', project(":${it.artifactId}"))
} else {
def version = it.version.text() ? it.version.text() : dependencyVersions["${it.groupId}:${it.artifactId}"]
def dep = "${it.groupId}:${it.artifactId}:${version}"
def scope = it.scope.text() ? it.scope.text() : 'compile'
if(scope == 'compile')
add('implementation', dep)
else if(scope == 'test') {
add('testImplementation', dep)
} else {
throw new Exception("Unrecognized dependency scope: $scope")
}
}
}
}
sourceCompatibility = '1.8'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
}
The above almost works. Direct dependencies are added as they should be but the problem is that transitive dependencies are not available at compile-time. How can I configure the subproject such that any transitive dependencies are resolved and added to the subprojects as well?
If you are intending for a module/subproject to be consumed as a dependency or library from another subproject/project, then you should use the Java Library plugin instead of the Java plugin
With the Java Library plugin, you will have access to the api configuration. You can read more about implementation vs api in API and implementation separation docs.
So your Gradle file could be:
dependencies {
implementation 'org.scala-lang:scala-library:2.13.3'
// ... Global deps ...
new XmlSlurper().parse("$projectDir/pom.xml").dependencies.dependency.each {
if(it.groupId.text() == 'my.org') {
add('api', project(":${it.artifactId}"))
} else {
def version = it.version.text() ? it.version.text() : dependencyVersions["${it.groupId}:${it.artifactId}"]
def dep = "${it.groupId}:${it.artifactId}:${version}"
def scope = it.scope.text() ? it.scope.text() : 'compile'
if(scope == 'compile')
add('api', dep)
else if(scope == 'test') {
add('testImplementation', dep)
} else {
throw new Exception("Unrecognized dependency scope: $scope")
}
}
}
}
The only thing different here is switching from implementation to api.
I am switching a play app from SBT to gradle and the routes and reverse routes scala files are not being generated with
import _root_.play.libs.F
which is causing
build/src/play/binary/routesScalaSources/controllers/ReverseRoutes.scala:260: not found: value F
def validate(accountId:F.Option[java.lang.Long]): Call = {
I am using gradle 3.5, play: '2.4.8', scala: '2.11' and java: '1.8'. Does anyone know if there is a compatibility issue with or some other known issue that is stopping the import from being added to the generated scala file?
** EDIT **
I found this class RoutesCompile with a method additionalImports but I can't find how to use it in the build.gradle file. (I am super new to gradle, more of a maven guy)
** EDIT 2 **
Based on the Javadoc in the RoutesCompile class it seems like I should be adding it to the model like this:
model {
components {
play {
platform play: '2.4.8', scala: '2.11', java: '1.8'
injectedRoutesGenerator = true
additionalImports = ['play.libs.F']
sources {
twirlTemplates {
defaultImports = TwirlImports.JAVA
source.srcDir "assets/views"
source.exclude "assets/stylesheets"
}
}
}
}
}
But I get the following error:
> Exception thrown while executing model rule: play { ... } # build.gradle line 147, column 9
> No such property: additionalImports for class: org.gradle.play.PlayApplicationSpec
I have finally found the answer to my issue. I needed to get the task and add the additional import that way.
model {
components {
play {
platform play: '2.4.8', scala: '2.11', java: '1.8'
injectedRoutesGenerator = true
tasks.withType(RoutesCompile) {
additionalImports = ['play.libs.F']
}
sources {
twirlTemplates {
defaultImports = TwirlImports.JAVA
source.srcDir "assets/views"
source.exclude "assets/stylesheets"
}
}
}
}
}
Using Gradle, I want to ensure appropriate dependency management in a large project such that module A cannot depend on module B (even indirectly). How would I go about doing this?
You can analyze all dependencies and throw an exception if you find a inappropriate one. Here's a code that does it for a specific dependency on classpath:
apply plugin: 'java'
repositories {
mavenCentral()
}
// This is just to have some dependencies on the classpath.
dependencies {
compile 'org.springframework.boot:spring-boot-starter:1.5.1.RELEASE'
compile "org.webjars:webjars-locator:+"
}
// run this task to analyze all deps
task checkDeps {
doLast {
// this closure simply prints a given dependency and throws an exception if slf4j-api is found
def failIfBad = { dep ->
println "CHECKING: $dep.module.id.group:$dep.module.id.name"
if (dep.module.id.name == 'slf4j-api') {
throw new GradleException("$dep.module.id.group:$dep.module.id.name on classpath!")
}
}
// this is a closure with recursion that calls the above failCheck on all children and their children
def checkChildren
checkChildren = { dep ->
if (dep.children.size() != 0) {
dep.children.each { child ->
failIfBad(child)
checkChildren(child)
}
}
}
// this is how you get all dependencies in the compile scope, iterate on the first level deps and then their children
configurations.compile.resolvedConfiguration.firstLevelModuleDependencies.each { firstLevelDep ->
failIfBad(firstLevelDep);
checkChildren(firstLevelDep);
}
}
}
The whole code could probably be optimized and more sophisticated rules will be necessary, but it should give you what you need to get started.
I'm new to Gradle and Groovy, and I'd hope there would be something to solve my problem.
I have several packages, each of which needs to be compiled into one jar.
One solution I've found is to create multiple tasks that are of Jar type, but I'd like to avoid copy/paste and end up with a giant gradle file whenever I add a new package to my project.
My current implementation is to have multiple jar tasks, like this one :
task jarFoo(type: Jar) {
baseName = "foo"
version = "1.0.0"
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
It works like a charm, however I add packages very often and I will end up with a lot of packages, therefore a lot of tasks and a lot of copied/pasted code.
After fiddling with build.gradle file, I've found that I needed to extend from Jar in order to get a jar created.
So here's the code for the class so far :
class JarTask extends Jar {
String jarName = "default"
String jarVersion = "1.0.0"
#TaskAction
def jar() {
baseName = jarName
version = jarVersion
String className = baseName.capitalize()
// Thanks Opal for reminding that sourceSets
// is defined in project.
from(project.sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
task jarFoo(type: JarTask) {
jarName = "foo"
}
task jarBar(type: JarTask) {
jarName = "bar"
jarVersion = "1.2.42"
}
The problem is that the jar that is created ignores basically everything in the method: it contains only a MANIFEST.MF containing one line with the manifest version and is given the name of the project, not the name given in task. Nothing else.
If needed, you can find the code online in my GitHub repo (mainly in French).
Any idea would be truly appreciated!
Here is another easier option that allows to pass parameters. I found the inspiration on this topic : https://discuss.gradle.org/t/passing-arguments-to-a-task/8427/20, which sounds exactly like what I was trying to do.
Here we basically define a method that returns a task, given some parameters. The rest is just testing if a version is given, or the code already given in question and adapted with #Opal great help.
It is sufficient to include the new builds in the artifacts block to make tasks available. Then, just run gradle jarqcm to build a single package or gradle assemble to compile everything.
apply plugin: "idea"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile "com.intellij:forms_rt:7.0.3"
runtime "com.intellij:forms_rt:7.0.3"
}
def jarPackage(artifactName, artifactVersion) {
if (artifactVersion == "" || artifactVersion == null) {
artifactVersion = "1.0.0"
}
return tasks.create("jar${artifactName}", Jar) {
baseName = artifactName
version = artifactVersion
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
artifacts {
archives jarPackage("aleatoire", ""), jarPackage("calculatrice", "1.2.3"), jarPackage("copier", ""),
jarPackage("qcm", "1.0.0")
}
After you edited the question is easy. There's no property sourceSets for the given task (Jar in this case). sourceSets are defined on Project and every task that extends DefaultTask inherits project field from it's parent. So you just need:
from(project.sourceSets.main.output) {
include "$baseName/**"
}
ANSWER
I hope you understand the difference between task configuration and execution phase. This is the problem that occurs here. Basically you extended Jar task which as all tasks of type Copy is not designed to be extended - see here. In task action you configure the artifacts to be copied but.. there's too late for configuration - it's execution phase. To solve the problem task rules may be used. I've modified the script and it's:
apply plugin: "idea"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile "com.intellij:forms_rt:7.0.3"
runtime "com.intellij:forms_rt:7.0.3"
}
tasks.addRule('Pattern: build<ID>') { String taskName ->
if (taskName.startsWith('build')) {
task(taskName, type: Jar) {
baseName = taskName - 'build'
version = '1.0.0'
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
}
artifacts {
archives project.tasks['buildqcm'], project.tasks['buildlistage'] //etc
}
and should invoked simply with gradle buildlistage buildqcm. You can make additional validation to check if <ID> passed is on the list of packages e.g. Hope that helps and sorry for having to wait so long :/