Project Stage |
---|
ZIO Shield statically analyses the source code, enforcing best coding practices with ZIO.
It aims to keep your code pure, total and clean with the help of powerful ZIO ecosystem.
Powered by Scalafix and Scalazzi rules.
Add zio-shield
sbt plugin to your project/plugins.sbt
:
addSbtPlugin("dev.zio" % "zio-shield" % "0.1.0")
It will add semanticdb-scalac
compiler plugin and -Yrangepos
scalac option
to your project settings if they doesn't exist.
They are needed to generate SemanticDb
files for static analysis.
Running shield
command will start the analysis.
> shield
[warn] ZioShieldShowcase.scala:23:7: error: possibly nullable
[warn] def nullable(): Response = {
[warn] ^^^^^^^^
[warn] ZioShieldShowcase.scala:24:18: error: nullable: null usage
[warn] GoodResponse(null)
[warn] ^^^^
[warn] ZioShieldShowcase.scala:27:7: error: possibly nullable
[warn] def handleResponse(response: Response): Unit = {
[warn] ^^^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:40:24: error: possibly nullable
[warn] handleResponse(nullable())
[warn] ^^^^^^^^
[warn] ZioShieldShowcase.scala:27:7: error: possible partial symbol
[warn] def handleResponse(response: Response): Unit = {
[warn] ^^^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:32:7: error: not total: throwing exceptions
[warn] throw new RuntimeException("Bad response!")
[warn] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:28:18: error: type casting
[warn] if (response.isInstanceOf[BadResponse]) {
[warn] ^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:29:34: error: type casting
[warn] val badResponse = response.asInstanceOf[BadResponse]
[warn] ^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:34:35: error: type casting
[warn] val goodResponse = response.asInstanceOf[GoodResponse]
[warn] ^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:39:9: error: ignored expression
[warn] handleResponse(alwaysGood())
[warn] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:40:9: error: ignored expression
[warn] handleResponse(nullable())
[warn] ^^^^^^^^^^^^^^^^^^^^^^^^^^
[warn] ZioShieldShowcase.scala:8:7: error: Future returning method
[warn] def bigComputation(data: String): Future[Int] = Future {
[warn] ^^^^^^^^^^^^^^
...
ZioShieldShowcase.scala
source code located here.
You can set shieldFatalWarnings
sbt setting to make all warnings fatal,
blocking you build if there are any problems detected by ZIO Shield.
shieldFatalWarnings := true
> shield
[error] ZioShieldShowcase.scala:23:7: error: possibly nullable
[error] def nullable(): Response = {
[error] ^^^^^^^^
...
To exlude specific rules from analysis you can create .shield.yaml
file in the project root and specify exludedRules
option.
# .shield.yaml
excludedRules: [ZioShieldNoIgnoredExpressions]
For using ZIO Shield with metals you should provide custom version of metals language server.
In vscode it can be done in your settings.json
:
"metals.customRepositories": ["central", "bintray:vovapolu/maven"],
"metals.serverVersion": "0.7.6-zio-shield-RC0"
And then run Metals: Restart server
command or just restart the editor.
-
Warnings are not shown
Run
Metals: Import build
in vscode. If it doesn't help restart the editor and try again.
ZioShieldNoFutureMethods
blocks anyval
ordef
that has type ofFuture[...]
ZioShieldNoIgnoredExpressions
blocks ignored expressions except inZIO.effect*
blocksZioShieldNoReflection
blocks all methods fromscala.reflect
,java.lang.reflect
andjava.lang.Class
ZioShieldNoTypeCasting
blocksasInstanceOf
,isInstanceOf
and anycase x: Y
except inZIO.effect*
blocksZioShieldNoImpurity
blocks direct usages ofUnit
returning methods and indirect usages through other methods except inZIO.effect*
blocksZioShieldNoIndirectUse
blocks "effectful" methods, which contain usages ofZIO.effect*
, expect when they are defined in ancestors of "pure" traits, i.e. traits without methods that useZIO.effect*
.ZioShieldNoNull
blocks directnull
usages and indirect usages through other methods except inZIO.effect*
blocksZioShieldNoPartial
blocks directthrow
andtry {...} catch ...
usages and indirect usages through other methods except inZIO.effect*
blocks