SBT plugin for enforcing rules on project dependencies.
SBT version support:
Supported major SBT version | Built against concrete SBT Version | Build JDK version |
---|---|---|
1 | 1.4.5 | 1.8 |
2 | 2.0.0-RC6 | 1.8 |
If your SBT version is earlier than the build SBT version, the plugin might still work, but the support is not guaranteed.
To get started, add the following line to your project/plugins.sbt
:
addSbtPlugin("com.evolution" % "sbt-dependency-rules-plugin" % "LATEST_VERSION")
Replace LATEST_VERSION
with the latest version of the plugin, which you can find on Maven Central.
The plugin is an AutoPlugin
, so it is automatically enabled.
By default, the rule set for dependencies is empty. Let's add some!
Add a wildcard import to the top of your build.sbt
to get access to all the plugin functionality:
import com.evolution.sbt.dependency_rules.*
Supposing you have a Pekko-based project, let us add some rules to all the SBT modules in the project:
ThisBuild / dependencyRules ++= Vector( // Ensure all Pekko dependencies have the same version to avoid annoying runtime errors! ExtraDependencyRules.Pekko.ModulesHaveSameVersion, // Ensure we do not get accidental transitive Akka dependencies ExtraDependencyRules.Akka.Banned, )
To check if your project's dependencies violate any of the defined rules, run the following task from your SBT console:
sbt dependencyRulesCheck
If there are any violations, the build will fail with an error message detailing the violations:
[error] [myPekkoApp][compile][AkkaBanned] banned: com.typesafe.akka:akka-actor_2.13:2.6.21 [error] (dependencyRulesCheck) com.evolution.sbt.dependency_rules.DependencyRulesViolated: AkkaBanned:compile
Here we have the AkkaBanned
rule violated in the compile
scope in the myPekkoApp
module.
Use the trusty SBT dependency tree functionality!
sbt "myPekkoApp/whatDependsOn com.typesafe.akka akka-actor_2.13 2.6.21"
You can ban a library entirely from your project. For example, to ban the Apache Log4j 1 library, you can define a rule like this:
import com.evolution.sbt.dependency_rules.* import sbt.* ThisBuild / dependencyRules += DependencyRule.banned( name = "NoLog4j1", // selector works on module coordinates: organization, name, revision // see SBT documentation for moduleFilter syntax: https://www.scala-sbt.org/1.x/docs/Update-Report.html#ModuleFilter selector = moduleFilter(organization = "log4j") )
Let's say you want to ensure that all Typelevel Cats modules have the same version:
import com.evolution.sbt.dependency_rules.* import sbt.* ThisBuild / dependencyRules += DependencyRule.sameVersion( name = "CatsModulesHaveSameVersion", // selector works on module coordinates: organization, name, revision // see SBT documentation for moduleFilter syntax: https://www.scala-sbt.org/1.x/docs/Update-Report.html#ModuleFilter selector = moduleFilter( organization = "org.typelevel", name = "cats-*", ), )
By default, rules are checked against the Compile
and Test
configurations. You can customize the scope of a rule using the withScope
or modifyScope
methods:
import com.evolution.sbt.dependency_rules.* import sbt.* ThisBuild / dependencyRules += ExtraDependencyRules.Pekko.ModulesHaveSameVersion.modifyScope(_ - Test)
The sbt-dependency-rules-plugin
works by analyzing the classpath of your project for each configuration (e.g., Compile
, Test
). It then applies the defined rules to the resolved dependencies.
Each rule has a logic
component that performs the actual verification. If the logic finds a violation, it reports an error, and the dependencyRulesCheck
task fails.
The plugin comes with a set of predefined rules in ExtraDependencyRules
for common use cases, and you can create your own custom rules.
The GitHub Actions CI build is done using JDK 1.8, but locally you can use any JDK up to 17 (including).
To reformat code using scalafmt, run:
sbt fmt
Code formatting is verified in build commands, and PRs with malformed code will not be accepted.
A fast build without scripted
tests can be run with:
sbt buildFast
A full build with scripted
tests can be run with:
sbt buildFull
- Being on the up-to-date main branch, create a release tag:
git tag v1.2.3
- Push the tag:
git push origin v1.2.3
- This will trigger the release GitHub Action. If it succeeds, the release ends up on Maven Central with GitHub release notes generated automatically from PRs info.
- If the release GitHub Action fails, the tag will be deleted on remote. After deleting the tag locally, fix the main branch and do the process again:
git tag -d v1.2.3
-
dependencyRules: SettingKey[Seq[DependencyRule]]
Dependency rules to be enforced.
-
dependencyRulesCheck: TaskKey[Unit]
Check the project's dependencies against the rules.
The ExtraDependencyRules
object provides the following predefined rules:
ExtraDependencyRules.Akka.ModulesHaveSameVersion
: Ensures all Akka modules have the same version.ExtraDependencyRules.Akka.Banned
: Bans all Akka modules.ExtraDependencyRules.Pekko.ModulesHaveSameVersion
: Ensures all Pekko modules have the same version.ExtraDependencyRules.Pekko.Banned
: Bans all Pekko modules.
You can create custom rules using the factory methods in the DependencyRule
companion object:
DependencyRule.sameVersion(name: String, scope: Set[Configuration], selector: ModuleID => Boolean)
: Requires all selected dependencies to have the same version.DependencyRule.banned(name: String, scope: Set[Configuration], selector: ModuleID => Boolean)
: Prohibits selected dependencies.DependencyRule(name: String, scope: Set[Configuration], logic: DependencyRuleLogic)
: Creates a rule with custom logic.