This plugin adds a verification task to the build that executes Degraph dependency checks on the sources of the gradle project. It will detect package cycles without any additional configuration. Using custom configuration settings you can define which package dependencies are allowed and which should be rejected.
The latest version uses Degraph 0.1.4
Important note: the development on this project has stopped, mainly because Degraph isn't actively maintained any longer. I have started a new project Decycle (written in Java), that detects cycles, displays them as HTML, but removes the output for yed. It supports Java ≥ 11 and provides both a Gradle and a Maven plugin.
The plugin has been released on the Gradle Plugin Repository. The latest version is 0.1.4.1 and requires at least Gradle version 4.1.
To use the plugin in your own project just add the following to your build.gradle
:
plugins {
id "de.obqo.gradle.degraph" version "0.1.4.1"
}
The plugin creates for each source set a corresponding degraphSourceSetName
task.
Additionally there is one degraph
task that runs all these source set specific tasks.
You can run a single degraph check (for example for the main
source set) with
gradle degraphMain
You can run all degraph checks with
gradle degraph
The degraph
task has a dependency on the check
task, so it will be executed together with other verification tasks if you run
gradle check
The result of each source set specific degraph task will be written to a corresponding file $buildDir/reports/degraph/name.graphml
(where name is the name of the source set) in the
GraphML format.
The plugin adds a degraph
configuration object to the build, that offers corresponding settings to those described in
the Degraph Manual (see in particular the Testing) section.
All configuration settings are optional.
degraph { toolVersion '0.1.4' sourceSets sourceSets.main, sourceSets.test, ... including 'org.example.includes.**', ... excluding 'org.example.excludes.**', ... slicings { name1 { patterns 'org.example.(*).**', ... allow 'a', 'b', ... allowDirect 'x', 'y', ... } name2 { ... } } }
(Note: technically all configuration settings are method calls and no property assignments.
So you have to use toolVersion ...
or even toolVersion(...)
instead of toolVersion = ...
)
-
toolVersion
defines the version of degraph to be used. The default value is'0.1.4'
(Note: newer versions of degraph have to be API compatible with version 0.1.4 for this to work) -
sourceSets
defines the source sets that should be analyzed. By default all source sets defined in the gradle build file are considered. That means this option is most useful if you only want a subset of the source sets to be checked. -
including
defines ant style string patterns for the classes that should be included (default: all) -
excluding
defines ant style string patterns for the classes that should be excluded (default: none) -
slicings
starts the slicings block, each slicing is defined by its name (also known as slicing type). A slicing configuration contains:patterns
a list containing unnamed patterns (String) or named patterns. A named pattern is defined usingnamedPattern(name, pattern)
.
Note: in a named pattern the name comes first, like in the Scala Constraint DSL, but unlike in the Java Constraint DSLallow
defines a simple constraint on the defined slicesallowDirect
defines a strict constraint on the defined slices. As constraints (both simple and strict) you can use- a string (referencing the name of the pattern/slice)
anyOf(slice, ...)
, see Unspecified order of slicesoneOf(slice, ...)
, see One of many slices
-
Note: there is no
noJars
option. Thedegraph
task will use only the outputs of the given source sets, which don't include jars by default.
Here are some examples from the degraph manual and their corresponding gradle configuration:
Slicing configuration in the Scala Constraint DSL:
classpath.including("de.schauderhaft.**") //
.withSlicing("module", "de.schauderhaft.(*).**") // use the third part of the package name as the module name
.withSlicing("layer",
("persistence","de.schauderhaft.legacy.db.**"), // consider everything in the package de.schauderhaft.legacy.db and subpackages as as part of the layer "persistence"
"de.schauderhaft.*.(*).**") // for everything else use the fourth part of the package name as
)
Gradle:
degraph {
including 'de.schauderhaft.**'
slicings {
module {
patterns 'de.schauderhaft.(*).**'
}
layer {
patterns(namedPattern('persistence', 'de.schauderhaft.legacy.db.**'),
'de.schauderhaft.*.(*).**')
}
}
}
Slice constraints in the Scala Constraint DSL:
classpath
.withSlicing("module", "de.schauderhaft.degraph.(*).**")
.allow("check", anyOf("configuration", "graph"), "model")
Gradle:
degraph {
slicings {
module {
patterns 'de.schauderhaft.degraph.(*).**'
allow 'check', anyOf('configuration', 'graph'), 'model'
}
}
}
After cloning this repository you can build and deploy a version of the gradle degraph plugin to your local maven repository by running
gradlew build publishToMavenLocal
Then add the following configuration to your project's build.gradle
:
buildscript {
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'de.obqo.gradle:gradle-degraph:0.1.4.1'
}
}
apply plugin: 'de.obqo.gradle.degraph'